在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
继承了类型为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();
}
我以前没有遇到过这种特殊类型的体系结构问题,请将其提交到“ 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();
}
}