2

我在理解以下代码时遇到问题(针对行号进行了注释)

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)
4

2 回答 2

7

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

当您调用该方法时:

base1.m1("");

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

void m1(Object o) { }

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


现在,第二次调用:

base.m2(o);

再次声明的类型baseBase。而Base类中的匹配方法是:

void m2(String o) { }

由于您无法传递接受Objecta 的参考String。编译器给你编译器错误。没有隐式缩小转换。


你可以通过一个简单的作业更清楚地理解它:

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

Java 不执行隐式缩小转换。obj从to的分配str不应该是有效的,因为否则你会ClassCastException在运行时得到 a 。

于 2013-09-19T18:30:15.020 回答
4

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

告诉编译器把它base当作一个Base,用Base base = ....

因此,根据您的指示,编译器将baseBase不知道任何Base可能扩展或可能不扩展的任何子类的情况下将其视为 a ,并且它(正确地)指出base可能不支持m2任意Object.

于 2013-09-19T18:30:31.873 回答