带有重载的Java函数调用

时间:2018-10-19 08:14:36

标签: java overloading

我想知道为什么第三输出不是b。

这是我的代码:

public class SimpleTests {
    public void func(A a) {
        System.out.println("Hi A");
    }
    public void func(B b) {
        System.out.println("Hi B");
    }
    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        A c = new B();
        SimpleTests i = new SimpleTests();
        i.func(a);
        i.func(b);
        i.func(c);
    }
}
class A {}
class B extends A {}

这是输出:

Hi A
Hi B
Hi A

有人可以告诉我为什么第三输出是Hi A而不是Hi B。因为实数c是B的实例。

3 个答案:

答案 0 :(得分:16)

您将重载与多态性混淆了。

具有多态性,当创建作为类A的子类的类B的实例(由类A的对象引用)并覆盖类A的方法时,调用该方法将执行类B的方法。

通过重载,被调用的方法仅知道参数声明的类型,而不知道初始化。

public class A {
    public void print() {
        System.out.println("A");
    }
}

public class B extends A {
    @Override
    public void print() {
        System.out.println("B");
    }
}    

public class Main {
    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        A otherB = new B();
        a.print();
        b.print();
        otherB.print();
    }
}

这将输出

A
B
B

答案 1 :(得分:11)

对重载方法的调用是在编译时根据参数的引用类型(A)而不是在运行时基于对象类型(B)来解决的。您已将变量声明为A类型,因此将其视为A类型。

答案 2 :(得分:3)

JLS §8.4.9. Overloading:

  

调用方法时,实际参数的数量(以及任何   显式类型参数)和参数的编译时类型   在编译时用于确定方法的签名   将会被调用。

您的示例中的编译时类型为:

A a = new A(); // A
^

B b = new B(); // B
^

A c = new B(); // A
^

因此,输出为:

Hi A
Hi B
Hi A