在Java中,我有一个抽象基类,例如WrapX,它包含一个类型为X的类型的属性(认为Decorator DP)。此类提供了一种方法来调用封装的X上的特定方法:

public abstract class WrapX{

  protected X instance;

  public WrapX(X x){
     this.instance = x;
  }

  public void foo(){
       instance.foo();
  }

}

public class X {

   public void foo(){
       System.out.println("foo");
   }
}


然后有一个名为Y的类,该类从X扩展并提供其他方法:

public class Y extends X {

  public void bar(){
     System.out.println("bar");
  }
}


然后自然地我创建了WrapY,可以用作Y类型上的修饰类型:

public class WrapY extends WrapX{

  ...

  public void bar(){
    instance.bar();
  }

}


因此,这就是问题所在。 WrapY已从其父instance继承了类型为XWrapX属性。就Eclipse而言,instanceX类型,因此会抱怨它不包含方法.bar()

当然足够公平,但是我们如何才能在此子类中将instance隐式转换为instanceY(初始类型为X的有效子类)...而无需显式强制转换乱码,还是变量阴影?

如果我在构造函数中有这个:

public WrapY(Y y){
 this.instance = y;
}


Eclipse仍然抱怨.bar()不是X类型的方法,因为我想它不能确定在构造WrapY(Y y)实例之前将使用WrapY

public void bar(){
        instance.bar(); // ERROR
      }


这是我目前的方法,到处都是演员:

public WrapY(Y y){
 (Y)instance = y;
}

public void bar(){
  ((Y)instance).bar();
}


我以前没有遇到过这种特殊类型的体系结构问题,请将其提交到“ Decorator-Based-Inheritance-Type-Casting”(!)下。请向我介绍如何更好地对此模型进行建模办法。

另一个问题是,如果将来有人扩展WrapY,则他们的类继承的实例类型将是X的自然(非广播)类型,而他们可以合理地假定它应该是Y类型。

谢谢

最佳答案

您可以使Wrap类具有通用性,例如:

public abstract class Wrap<T extends X>{

    protected T instance;

    public Wrap(T x){
        this.instance = x;
    }

    public void foo(){
       instance.foo();
    }
}



public final class WrapY extends Wrap<Y> {

    public WrapY(Y y) {
        super(y);
    }

    public void bar(){
        instance.bar();
    }
}


那么对于WrapY的实例,instance将是Y



更新:
如果您也想从WrapY继承(并解决最后一个包装类型最合适的问题),请执行以下操作:

public class WrapY<U extends Y> extends Wrap<U> {

    public WrapY(U y) {
        super(y);
    }

    public void bar(){
        instance.bar();
    }
}

08-28 18:32