Java 具有抽象字段和子类化(无强制转换)的抽象类

Java 具有抽象字段和子类化(无强制转换)的抽象类,java,generics,design-patterns,Java,Generics,Design Patterns,我创建了一个抽象基类。它包含一个对象,该对象应由任何子类扩展: public abstract class AbstractParent { protected AbstractObject subMePlz; // ... some fields that all subclasses need public AbstractParent() { this.subMePlz = createThisInYourExtendedClass();

我创建了一个抽象基类。它包含一个对象,该对象应由任何子类扩展:

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

    }

    public abstract AbstractObject createThisInYourExtendedClass();
} 
抽象对象:

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);  
   }
}
需要一个比较器会改变我应该如何实现它吗我想用一个通用的比较器来表示其子类可以使用的抽象对象列表。

您有两个选择:

放弃项目以在超类中声明字段。相反,向超类添加一个内部抽象getter方法-基本上,AbstractParent应该有一个方法AbstractAbstractObject getSubemplz。 使用泛型在子类中设置Subemplz的类型:定义AbstractParent以使其Subemplz字段具有T。
就我个人而言,我经常发现选项1的可扩展性非常好——例如,您可以拥有另一个子类,该子类可以在不声明getSubMePlz返回类型的情况下缩小getSubMePlz返回类型的范围,这可能是有利的。

听起来您需要将其设置为泛型:

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> {
    ...
}
请注意,在构造函数中调用非私有方法通常不是一个好主意-子类还没有完全初始化,这会使您很难推断您真正可以依赖多少方法。

为什么不使用这个-

     super.subMePlz
与此相反——

    (ConcreteObject)this.subMePlz

这样,你就不需要石膏了

您只需在子类中保存对象的副本,但使用正确的类即可

public class ExtendParent extends AbstractParent {
  ConcreteObject concreteObject;

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

  ...

对于选项1,这是否是抽象的T getSubMePlz?选项1根本不涉及任何泛型,尽管我认为您可以将两者结合起来。