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

Java 如果我对输出的解释是正确的,java,output,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

代码:

输出为

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");
    }
}
因此,
B::bar
被覆盖,
B::foo
被重载,当函数被重载时,引用的数据类型才是重要的,而不是它指向的对象的类型。我说得对吗

当函数重载时,重要的是引用的数据类型,而不是它所指向的对象的类型。我说得对吗


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

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

  • TestA.bar(字符串)
    TestB.bar(字符串)
  • TestA.foo(字符串…
    TestB
    继承,然后在
    TestB
    中使用
    TestB.foo(字符串)

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

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

@TedHopp:我写道:
重写是运行时绑定。
。好吧,我显然太困了,无法让所有的overwhater都保持正常。注释已删除。实际输出与您提到的情况不同。@IanMcGrath-Ack。我在我的测试程序中看到一个输入错误。我将编辑我的答案。
TestA::foo
TestB::bar