重新构建一个继承的字段

时间:2014-04-18 14:37:33

标签: java inheritance casting

B继承AD继承CD个实例已通过B个实例进行操作,但未覆盖变量或创建新的引用D类型无法看到bStuff()

class Ryrich_A { 
  public void aStuff() { System.out.println("a-type stuff"); }
}
class Ryrich_B extends Ryrich_A { 
  public void bStuff() { System.out.println("b-type stuff"); }
}

class Ryrich_C { 
  Ryrich_A a; 
  Ryrich_C(Ryrich_A a) { 
    this.a = a; 
  }
}

class Ryrich_D extends Ryrich_C{    
  Ryrich_D(Ryrich_B b) {
    super(b);
  }

  public void doStuff() {
    a.aStuff();
    // a.bStuff();  --problem--
  }

  public static void main(String[] args) {
    new Ryrich_D(new Ryrich_B()).doStuff();
  }
}

4 个答案:

答案 0 :(得分:2)

如果C的子类应该与A的特定子类一起使用(即D始终与B一起使用),则可以使C通用:

class C<T extends A> { 
    T a; 
    C(T a) { 
        this.a = a; 
    }
    ...
}

class D extends C<B> {    
    D(B b) {
        super(b);
    }
    ...
}

答案 1 :(得分:1)

即,当然,因为班级a中的成员变量C属于A而非B

因此,在课程doStuff中的方法D中,您无法调用a上仅存在于课程B中的任何方法 - 该方法不会{39}知道a确实是指B

你只能通过D的{​​{1}}方法(这不是很好)进行强制转换,或者通过更改doStuff的类型来解决这个问题。等级aC

B

答案 2 :(得分:1)

如果你覆盖B类中的方法,我认为你得到了理想的结果。

class A { 
    public void doStuff() { System.out.println("a-type stuff"); }
}

class B extends A { 
    public void doStuff() { System.out.println("b-type stuff"); }
}

class C { 
    A a; 
    C(A a) { 
        this.a = a; 
    }
}

class D extends C{
    D(B b) {
        super(b);
    }

    public void doStuff() {
         a.doStuff(); //calls B's doStuff method
    }

    public static void main(String[] args) {
        new D(new B()).doStuff();
    }
}

答案 3 :(得分:1)

它无法看到它,因为a中的class C属于A类型。

以下是我在很多地方看到的一个例子,但它仍然有帮助。

class Animal
{
    public void eat(){
        System.out.println("Animal eats something");
    }
    public void organic(){
        System.out.println("Animals are organic");
    }

}
class Dog extends Animal
{
    @Override
    public void eat(){
        System.out.println("Dog eats something");
    }
    public void eat(String food){
        System.out.println("Dog eats +"food);
    }
    public void bark(){
        System.out.println("Dog barks");
    }
}

Animal dog =  new Dog();

dog.eat();                  //Dog eats something

((Animal)dog).eat();        //Dog eats something    

//Still we get Dog's eat(). There is no way you could call eat() method of Animal using this dog.

((Dog)dog).eat("steak");    //Dog eats steak

//To call methods only in the subclass we need to cast it to the Object type

((Dog)dog).bark();          //Dog barks

//Same as above

dog.organic();              //Animals are organic

//With no worries we could call methods in Animal (Reference type)


Animal a = new Animal();
Dog d = (Animal)a;

//compiles but fails at runtime. If the types are in the same Inheritance tree, compiler says OK.

Animal a3 = new Animal();
Dog d1 = (Dog)a3;       

//compiles because compiler sees both Dog and Animal in same tree. But fails during runtime.

Dog d = new Dog();
Animal a1 = d;
Animal a2 = (Animal)d;

//Both compiles and runs fine.