Как выкинуть и использовать методы, специфичные для детей - PullRequest
1 голос
/ 04 апреля 2011

У меня следующая проблема:

//class XmlObject is part of org.apache.xmlbeans
public class DepartmentType extends XmlObject; // getName method is defined in this class
public class OrganizatiopnType extends XmlObject; // getName method is defined in this class

XmlObject department = null;
if (a == 1)
    department = (DepartmentType) order.getDepartment(); // returns DepartmentType
else
    department = (OrganizationType) order.getOrganization(); // returns OrganizationType

department.getName(); // throws cannot find symbol
// ... and do some other complex stuff using methods which are defined in both classes ...

Какой самый чистый способ вызова метода getName ()?

ОБНОВЛЕНИЕ 1:
Cybernate, ваш подход кажется наиболее логичным, если у вас есть контроль над DepartmentType & OrganizationType. К сожалению, эти объекты генерируются из XML-схемы с помощью xmlbeans. В моем случае я мог бы изменить схему, чтобы у обоих типов была общая база.

Но что, если я не смогу контролировать схему. Как я мог реализовать основную идею?

Ответы [ 4 ]

2 голосов
/ 04 апреля 2011

Примечание. Это альтернатива текущей иерархии классов.

Определите промежуточный класс с именем UnitTypeBase , который расширяет с XmlObject .Что-то вроде

public class UnitTypeBase extends XmlObject{
 public String getName(){
  //Some implementaition or you can mark it as abstract
 }
}

, затем производное * DepartmentType и OrganizationType * из UnitTypeBase

//class XmlObject is part of org.apache.xmlbeans 
public class DepartmentType extends UnitTypeBase; // getName method is defined in this class 
public class OrganizatiopnType extends UnitTypeBase; // getName method is defined in this class  
UnitTypeBase department = null; 
if (a == 1)     
  department = (DepartmentType) order.getDepartment(); // returns DepartmentType 
else     
     department = (OrganizationType) order.getOrganization(); // returns OrganizationType  
department.getName(); 
     // ... and do some other complex stuff using methods which are defined in both classes ... 
2 голосов
/ 04 апреля 2011

Я предлагаю вам сделать так, чтобы оба класса реализовали общий интерфейс, и вместо этого приводить к нему. Я не вижу, что ваши нынешние заклинания могут иметь какой-либо эффект ...

public interface NamedElement
{
    String getName();
}

...

NamedElement department = a == 1 ? order.getDepartment() : 
                                   order.getOrganisation();
String name = department.getName();

Предполагается, что вы, конечно, можете контролировать код DepartmentType и OrganizationType.

0 голосов
/ 05 апреля 2011

Если у вас есть контроль над вашей схемой, вы можете определить базовый абстрактный тип, из которого могут распространяться другие ваши типы. Я сам не пробовал, поэтому не уверен, как XmlBeans справится с этим.

<complexType name="NamedEntity" abstract="true">
    <sequence>
        <element name="name" type="string"/>
    </sequence>
</complexType>

<complexType name="DepartmentType">
    <complexContent>
        <extension base="NamedEntity">
            <sequence>
                <element name="whatever"/>
            </sequence>
        </extension>
    </complexContent>
</complexType>

В противном случае это обходной путь (хак?), Но вы можете использовать Commons BeanUtils , если ваши сгенерированные классы будут следовать соглашению об именах JavaBean. Если эти объекты часто передаются, вы можете создать класс-оболочку, чтобы сделать вызовы немного более конкретными.

public class Department {
    XmlObject obj;

    public Department(XmlObject obj){
        if(!obj instanceof DepartmentType || !obj instanceof OrganizatiopnType){
            throw new IllegalArgumentException();
        }
        this.obj = obj;
    }

    public String getName(){
        return (String)PropertyUtils.getProperty(obj, "name");
    }
}

Любая проблема может быть решена с помощью другого уровня косвенности ..... за исключением слишком большого количества косвенных указаний.

0 голосов
/ 04 апреля 2011

Создайте интерфейс с методом getName, и оба класса DepartmentType и OrganizationType реализуют этот интерфейс.Такие как

1002 *
...