B
继承A
,D
继承C
。 D
个实例已通过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();
}
}
答案 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
的类型来解决这个问题。等级a
到C
。
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.