0

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

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);  
   }
}

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

4

4 回答 4

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> {
    ...
}

请注意,在构造函数中调用非私有方法通常是一个坏主意 - 子类尚未完全初始化,这可能使您难以推断您真正可以依赖多少。

于 2012-04-24T16:51:54.193 回答
3

你有两个选择:

  1. 放弃项目以在超类中声明该字段。相反,向你的超类添加一个内部抽象“getter”方法——基本上,AbstractParent应该有一个方法abstract AbstractObject getSubMePlz()
  2. 使用泛型subMePlz在您的子类中设置类型:定义为它的字段AbstractParent<T>有一个。TsubMePlz

就个人而言,我经常发现选项 1 具有非常令人愉快的可扩展性——例如,您可以有另一个子类来缩小getSubMePlz()返回类型而不声明它,这可能是有利的。

于 2012-04-24T16:50:56.690 回答
0

为什么不使用这个 -

     super.subMePlz

而不是这个 -

    (ConcreteObject)this.subMePlz

这样,你就不需要演员表了。

于 2012-04-24T16:53:52.720 回答
0

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

public class ExtendParent extends AbstractParent {
  ConcreteObject concreteObject;

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

  ...
于 2012-04-24T16:57:16.087 回答