如何转换一个继承的封装属性来暴露子类的方法 - Java

时间:2012-10-06 09:47:37

标签: java eclipse inheritance casting decorator

在Java中我有一个抽象基类,比方说WrapX,它包含一个类型的属性,比如X(想想装饰者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继承了X类型的WrapX属性。就Eclipse而言,instance的类型为X,因此会抱怨它不包含方法.bar()

当然很公平,但是在这个子类中我们可以隐式地将instance强制转换为instance Y(初始类型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();
}

我之前没有遇到过这种特殊类型的架构问题,请在“基于装饰器的继承 - 类型 - 投射”(!)下进行归档...请告诉我如何对此进行建模以更好的方式。

另一个问题是,如果将来某人扩展WrapY,他们的类继承的实例类型将是X的自然(未发布)类型,当他们可能合理地认为它应该是输入Y

由于

1 个答案:

答案 0 :(得分:2)

您可以使您的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();
    }
}