2012-04-24 95 views
0

我创建了一个抽象基类。它包含应该由任何子类扩展的对象:抽象类与抽象字段和子类化没有铸造

public abstract class AbstractParent { 
    protected AbstractObject subMePlz; 
    // ... some fields that all subclasses need 
    public AbstractParent() { 
     this.subMePlz = createThisInYourExtendedClass(); 

    } 

    public abstract AbstractObject createThisInYourExtendedClass(); 
} 

的abstractObject:

public abstract class AbstractObject { 
    // ... some fields/methods that all subclasses need 
} 

我要的是能够使用扩展字段中扩展类无铸造:

public class ExtendParent extends AbstractParent { 
    // .. some unique fields 
    public ExtendParent(){ 
     super(); 
    } 


    public ConcreteObject createThisInYourExtendedClass(){ 
     return new ConcreteObject(); 
    } 

    // what I want to do - no cast 
    public void doSomethingWithSubMePlzWithoutCastingIt() { 
     System.out.println(this.subMePlz); 
    } 

    // what I end up doing - gotta cast 
    public void doSomethingWithSubMePlzWithoutCastingIt() { 
     System.out.println((ConcreteObject)this.subMePlz); 
    } 
} 

需要一个比较器改变我应该如何实现这个? - 我正在考虑一个通用的比较器,用于其子类可以使用的AbstractObjects列表。

回答

4

这听起来像你需要使它通用:

public abstract class AbstractParent<T extends AbstractObject> { 
    protected T subMePlz; 
    // ... some fields that all subclasses need 
    public AbstractParent() { 
     this.subMePlz = createThisInYourExtendedClass(); 

    } 

    public abstract T createThisInYourExtendedClass(); 
} 

public class ExtendParent extends AbstractParent<ConcreteObject> { 
    ... 
} 

注意,调用构造函数内的非私有方法是通常一个坏主意 - 子类不会被完全初始化还,这可能会使你很难推断你能够真正依赖多少。

3

你有两个选择:

  1. 放弃该项目申报的超领域。相反,将内部抽象“getter”方法添加到您的超类中 - 基本上,AbstractParent应该有一个方法abstract AbstractObject getSubMePlz()
  2. 在您的子类中使用泛型来设置subMePlz的类型:define AbstractParent<T>对其subMePlz字段具有T

就个人而言,我经常发现选项1是非常愉快扩展性 - 例如,你可以有其他子类,缩小,但仍未宣布它的getSubMePlz()返回类型,它可以是有利的。

+0

对于选项1会是抽象的T getSubMePlz()? – gebuh 2012-04-24 17:54:41

+0

选项1根本不涉及任何泛型,但我想你可以将两者结合起来。 – 2012-04-24 18:00:15

0

为什么不利用这一点 -

 super.subMePlz 

代替本 -

(ConcreteObject)this.subMePlz 

这样,你将不再需要转换。

0

您可以保存子类中的对象的副本,但具有正确的类。

public class ExtendParent extends AbstractParent { 
    ConcreteObject concreteObject; 

    public AbstractObject createThisInYourExtendedClass(){ 
    ConcreteObject concreteObject = new ConcreteObject(); 
    return concreteObject; 
    } 
    public void doSomethingWithSubMePlzWithoutCastingIt() { 
    System.out.println(concreteObject); 
    } 

    ...