【问题标题】:If my explanation for output is correct如果我对输出的解释是正确的
【发布时间】:2013-01-08 05:58:02
【问题描述】:

代码:

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 被重载,当函数重载时,引用的数据类型与其指向的对象类型无关。我说的对吗?

【问题讨论】:

    标签: java output


    【解决方案1】:

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

    是的。

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

    【讨论】:

    • @TedHopp:我写道:Overriding is run time binding.
    • 好吧,我显然太困了,无法保持一切正常。评论已删除。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

      • 实际输出与你提到的情况不同。
      • @IanMcGrath - 确认。我在我的测试程序中看到一个错字。我将编辑我的答案。
      猜你喜欢
      • 1970-01-01
      • 2014-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-11
      • 1970-01-01
      相关资源
      最近更新 更多