1

代码:

class TestA {
    public void foo(String... strings ) {
        System.out.println("TestA::foo");
    }

    public void bar(String a){
        System.out.println("TestA::bar");
    }
}

class TestB extends TestA {
    public void foo(String strings ) {
        System.out.println("TestB::foo");
    }

    public void bar(String a){
        System.out.println("TestB::bar");
    }

    public static void main(String[] args) {
        TestA a = new TestB();
        a.foo("foo");
        a.bar("bar");
    }
}

输出是

TestA::foo
TestB::bar

所以B::bar被覆盖并被B::foo重载,当一个函数被重载时,引用的数据类型与它指向的对象的类型无关。我对吗?

4

3 回答 3

1

当函数重载时,引用的数据类型与其指向的对象类型无关。我对吗?

是的。

重载是编译时绑定,当时只知道引用的类型。虽然覆盖是运行时绑定并根据对象类型执行调用。

于 2013-01-08T06:03:50.133 回答
1

我不确定您的分析到底是什么,但这是我所看到的:

  • TestA.bar(String)被覆盖TestB.bar(String)
  • TestA.foo(String...)被继承,TestB然后被重载TestBTestB.foo(String)

但是,因为编译器不知道a.foo("foo")正在为TestB对象调用它,所以它不知道重载。因此,它将其编译为对带有签名的方法的调用foo(String...)。如果它知道这a是 a TestB,它将绑定到,foo(String)因为这是一个更接近的匹配项(不需要转换为数组参数)。

于 2013-01-08T06:09:38.437 回答
1

TestB 类继承 TestA 并且它具有重写 bar 方法和重载 foo 方法,在编译 TestA 时 a 具有 TestB 的引用,因此重载方法不会被执行,但在重写 bar 方法的情况下调用被重写方法在运行时完成。因为重载的方法是在编译时加载的,而重载的方法是在运行时加载的。

于 2013-01-08T06:11:01.800 回答