无法理解java中的继承和覆盖/重载

时间:2013-09-19 18:27:42

标签: java inheritance override

我在理解下面的代码时遇到了问题(对行号进行了评论)

class Base {
    void m1(Object o) {
    }

    void m2(String o) {
    }
}

public class Overloading extends Base {

    void m1(String s) {
    }

    void m2(Object o) {
    }
public static void main(String[] args) {
    Object o = new Object();
    Base base1 = new Base();
    base1.m1("");//**why this works perfect**
    Base base = new Overloading();
    base.m2(o);// **why compile time error** - The method m2(String) in the type Base is not applicable for the arguments (Object)

2 个答案:

答案 0 :(得分:7)

编译器总是根据您调用它的引用的声明类型来解析方法调用。

调用方法时:

base1.m1("");

编译器在声明的base1类型中查找方法签名,在这种情况下为BaseBase中的匹配方法是:

void m1(Object o) { }

由于参数Object可以接受String参数,因此调用有效。您可以将子类对象传递给超类引用。


现在,第二次调用:

base.m2(o);

声明的base类型再次为BaseBase类中的匹配方法是:

void m2(String o) { }

由于您无法传递Object引用,而String被接受。编译器为您提供编译器错误。没有隐含的缩小转换。


您可以通过简单的任务更清楚地理解它:

Object ob = new Integer(3);
String str = ob;  // This shouldn't be valid

Java不执行隐式缩小转换。从objstr的分配不应该有效,否则您将在运行时获得ClassCastException

答案 1 :(得分:4)

在第base.m2(o)行,编译器不知道baseOverloading - 它只知道它是Base。为什么忘记了?因为你告诉它。

告诉编译器将base视为Base,并将其声明为Base base = ...

因此,根据您的说明,编译器会将base视为Base,而不了解任何可能延伸或不延伸的Base子类,以及它(正确)指出base可能不支持任意m2上的Object