Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何强制转换继承的封装属性以公开子类Java的方法_Java_Eclipse_Inheritance_Casting_Decorator - Fatal编程技术网

如何强制转换继承的封装属性以公开子类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

在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
的属性。就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();
    }
}