2014-11-15 91 views
1

在下面的代码:为什么调用基类方法?

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"); 
    } 
} 

回答

3

由于引用类型。

Base b = new Sub(); 
    b.show("str"); 
    Sub2 s2 = new Sub2(); 
    s2.show(""); 

在该代码中,虽然是bSub一个实例,该变量的引用类型是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?

+0

+1。究竟。关键是该子方法不会“覆盖”基类方法,但会超载它。我同意尽可能经常使用@Override。 –

0

您正在调用一个字符串,以便调用show()方法重载字符串。

也许你没有意识到sub2不会继承??

0

你声明的变量b的类型为基础的,那么你调用显示()就可以了。由于它有一个匹配签名的show方法,也就是调用的方法。

然后你声明你的变量s2是Sub2类型,并在其上调用show(String)。运行时由于匹配而调用该方法。

相关问题