在以下代码中:
b.show("str");
//prints: from base
d.show("");
//prints: from str
有人可以解释为什么它的表现不同吗? 我想知道为什么Base b = new Sub(),将调用来自基类的b.show()。 我只是使用DifferentClass,作为参考显示在非继承场合下调用b.show(String)。
public class TestClass {
public static void main(String[] args) {
Base b = new Sub();
b.show("str");
DifferentClass d = new DifferentClass ();
d.show("");
}
}
class Base {
public void show(Object obj) {
System.out.println("from base");
}
}
class Sub extends Base {
public void show(String str) {
System.out.println("from sub");
}
}
class DifferentClass {
public void show(String str) {
System.out.println("from str");
}
public void show(Object obj) {
System.out.println("from obj");
}
}
答案 0 :(得分:3)
由于引用类型。
Base b = new Sub();
b.show("str");
Sub2 s2 = new Sub2();
s2.show("");
在该代码中,尽管b
是Sub
的实例,但变量的引用类型为Base
。方法重载在编译时评估,而不是在运行时评估。这很重要,因为在编译时,一旦new Sub()
构造函数运行并且我们分配了变量,编译器就不再知道具体的类。只有它是有效的Base
。
为什么这很重要?
因为当编译器尝试解析b.show(String)
时,Base
上没有方法(它确实知道b
的唯一类型)String
,所以它将字符串传递给show(Object)
方法。
Sub
并未覆盖show(String)
方法(尽管Sub2
确实如此)。
顺便说一下,@Override
注释会帮助您:When do you use Java's @Override annotation and why?
答案 1 :(得分:0)
您正在使用字符串进行调用,因此调用了带有字符串重载的方法show()。
也许你没有意识到sub2没有继承?? ...
答案 2 :(得分:0)
您将变量b声明为Base类型,然后在其上调用show()。因为它有一个与签名匹配的show方法,即调用的方法。
然后将变量s2声明为Sub2类型,并在其上调用show(String)。运行时调用该方法,因为它匹配。