在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
从其父级 WrapX
继承了 X
类型的 instance
属性。就 Eclipse 而言,instance
的类型为 X
,因此会提示它不包含方法 .bar()
。
当然很公平,但是在这个子类中我们如何才能将实例
隐式转换为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
类型。
谢谢
最佳答案
您可以使 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();
}
}
关于java - 如何转换继承的封装属性以公开子类的方法 - Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12758641/