我有这个涉及继承,多态,重载和覆盖的问题。我理解所有这些条款但不确定它们是如何在这里工作的。这是代码:
class A {
public String show(D obj) {return "A and D";}
public String show(A obj) {return "A and A";}
}
class B extends A {
public String show(B obj) {return "B and B";}
public String show(A obj) {return "B and A";}
}
class C extends B{}
class D extends B{}
public class whatever {
public static void main(String[] args) {
A a = new B(); // note the B here
B b = new B();
C c = new C();
D d = new D();
System.out.println(a.show(a)); // B and A
System.out.println(a.show(b)); // B and A
System.out.println(a.show(c)); // B and A
System.out.println(a.show(d)); // A and D
}
}
所以这里的任务是找到输出。我已经有了答案,这些是我提出的意见。
我理解第一个,因为Java自动执行动态绑定,因此a.show()从B类调用show(),而a类型为A,因此调用B.show(A obj)。
最后一个也有意义,show()方法是重载的,因为d是D类型,所以调用A.show(D obj)继承自A类。
另外两个我遇到了麻烦。我明白这是有道理的,因为b和c在技术上都是A型对象,但为什么它与“B和A”相比“B和B”?
声明的a
类型是A
。
A只有两种方法:一种采用A(b和c都是A的实例),另一种采用D(b和c都不是D的实例)。
所以第一种方法匹配,第二种方法不匹配。所以第一种方法是由编译器选择的。
该方法在B中被覆盖,并且a
的具体类型是B,因此打印“B和A”。
方法B.show(B)
不会覆盖方法A.show(A)
,因为它不采用与参数相同的类型。
这里有两个概念,一个是重载,另一个是覆盖。当你创建A a = new B();它意味着a是B的对象并且具有A的类型。因此,当执行a.show(a)时,它首先遇到类A的show(A obj)和show(B obj)方法,然后将参数与A类型匹配,但'a'是B的实例,因此方法显示(A执行B类的obj)。
现在当执行a.show(c)时,它首先遇到类A的show(A obj)和show(B obj)方法,然后在类A中找不到与C类型的参数匹配,但仍然执行因为C类延伸B而B延伸A.
简而言之,我们可以说a.show(a)相当于a.show(b),相当于a.show(c)。