【问题标题】:How to upcast and use child specific methods如何向上转换和使用特定于儿童的方法
【发布时间】:2011-04-04 19:00:45
【问题描述】:

我有以下问题:

//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:
Cyber​​nate,如果您可以控制DepartmentTypeOrganizationType,您的方法似乎是最合乎逻辑的。不幸的是,这些对象是由 xmlbeans 从 XML 模式生成的。在我的例子中,我可以重新设计模式,让两种类型都有共同的基础。

但是,如果我无法控制架构怎么办。我如何才能实现基本思想?

【问题讨论】:

    标签: java xml casting xsd xmlbeans


    【解决方案1】:

    我建议你让两个类都实现一个通用接口,然后转换为那个接口。我看不出你目前的演员阵容有什么影响......

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

    当然,这是假设您可以控制 DepartmentTypeOrganizationType 代码。

    【讨论】:

    • 这就是问题所在,我无法控制DepartmentTypeOrganizationType,它们是由XSD 中的xmlbeans 从外部生成的。
    【解决方案2】:

    注意:这是当前类层次结构的替代方案。

    定义一个名为 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 ... 
    

    【讨论】:

    • 我建议使用接口而不是中间类 - 这样,如果必须在不同的类集中有两个这样的接口,它就可以正常工作。
    • @Jon:是的,这完全取决于上下文。如果 getName 需要跨越不同的类集,基于接口的方法会更好。
    • 如果我无法控制类型(它们是从外部生成的)怎么办?
    • @zeldi:如果您无法控制类型,那么这里提到的所有解决方案都不适用。然后,您必须对每种类型的检查进行硬编码...相应地对其进行转换,然后调用 getName 方法...我会等着看是否有人有更好的建议。
    • 我确实选择了 Adam B 的解决方案,但我仍然想听听您的替代解决方案。
    【解决方案3】:

    如果您可以控制架构,则可以定义一个基本抽象类型,您的其他类型可以从中扩展。我自己没有尝试过,所以我不确定 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>
    

    否则,这是一种变通方法(hack?),但您可以使用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");
        }
    }
    

    任何问题都可以通过另一层间接解决......除了太多间接。

    【讨论】:

      【解决方案4】:

      使用方法getName 创建一个接口,DepartmentType 和OrganizationType 类都实现了这个接口。比如;

      public class IName {
         public void getName();
      }
      
      public class DepartmentType extends XmlObject implements IName {}
      
      public class OrganizationType extends XmlObject implements IName {}
      
      IName department = null;
      if (a==1)
        department = order.getDepartment();
      else
       department = order.getOrganization();
      String name = department.getName();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多