如何强制转换继承的封装属性以公开子类Java的方法
在Java中,我有一个抽象基类,比如说如何强制转换继承的封装属性以公开子类Java的方法,java,eclipse,inheritance,casting,decorator,Java,Eclipse,Inheritance,Casting,Decorator,在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
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
的属性。就Eclipse而言,实例
的类型是X
,因此会抱怨它不包含任何方法.bar()
当然很公平,但是在这个子类中,我们如何将实例
隐式地强制转换为Y
的实例(初始类型X
的有效子类)。。。不需要在代码中乱丢显式的cast属性,或者变量阴影
如果我在构造器中有这个:
public WrapY(Y y){
this.instance = y;
}
Eclipse仍然抱怨.bar()
不是X
类型的方法,因为我猜它无法确定在构造WrapY
实例之前将使用WrapY(Y)
:
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扩展到WrapX
的WrapZ
,那么T在WrapZ
中仍然是Y
类型。如果我有WrapZ扩展WrapX
,那么WrapZ
将不会在继承层次结构中的正确位置,即它不会从WrapY
(因此不会从WrapY
继承方法/属性。您将如何解决此问题?是否需要将所有类都设置为泛型类?例如WrapY扩展WrapX
,以便我可以使用WrapZ扩展WrapY
?ThanksPerfect!非常感谢,这比我当前的实现更干净。特别是,考虑到某些类有相当多的方法!不过出于兴趣,如果WrapY是final,我不能从中扩展它?它需要是final吗?@HodeCode:sorry'关于复制和粘贴错误:在第二种情况下,您将WrapY泛化为可以从中继承-因此final没有多大意义。@DaveBall不必担心,我也这么怀疑!非常感谢您对本文的贡献马特的伟大解决方案
public class WrapY<U extends Y> extends Wrap<U> {
public WrapY(U y) {
super(y);
}
public void bar(){
instance.bar();
}
}