如果我对输出的解释是正确的

时间:2013-01-08 05:58:02

标签: java output

代码:

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被重载,并且当函数被重载时,它是引用的数据类型,而不是它指向的对象的类型。我是对的吗?

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

  

当一个函数被重载时,它是引用的数据类型,而不是它指向的对象类型。我是对的吗?

重载是编译时绑定,当时只知道引用类型。覆盖是运行时绑定,并且基于对象类型执行调用。

答案 2 :(得分:1)

我不确定你的分析究竟是什么,但这就是我所看到的:

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

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