使用继承的重载方法

Fed*_*ico 20 java methods inheritance integer numbers

我有两节课:

public class ClassA {
    public void method(Number n) {
        System.out.println("ClassA: " + n + " " + n.getClass());
    }
}
Run Code Online (Sandbox Code Playgroud)

和:

public class ClassB extends ClassA {            
    public void method(Integer d) {
        System.out.println("ClassB: " + d + " " + d.getClass());
    }
}
Run Code Online (Sandbox Code Playgroud)

但是当我跑步时:

ClassA a = new ClassB(); 
a.method(3);
Run Code Online (Sandbox Code Playgroud)

我明白了:

ClassA: 3 class java.lang.Integer
Run Code Online (Sandbox Code Playgroud)

我的问题是,为什么没有ClassB使用方法? a是的实例ClassB,以及ClassBmethod()有一个Integer参数...

Bhe*_*ung 25

我的问题是,为什么不使用ClassB的方法?

不对.使用的方法是ClassB继承自的方法ClassA.


我认为这里混淆的主要原因是该方法实际上没有被覆盖,而是重载.虽然Integer是子类型Number,但由于方法参数在Java中是不变的,因此该方法public void method(Integer d)不会覆盖该方法public void method(Number n).因此,ClassB最终会有两个(重载)方法.

静态绑定用于重载方法,编译器选择具有最特定参数类型的方法.但在这种情况下,为什么编译器选择public void method(Number n)而不是public void method(Integer d).这是因为您用于调用方法的引用是类型的ClassA.

ClassA a = new ClassB(); //instance is of ClassB (runtime info)
a.method(3);             //but the reference of type ClassA (compiletime info)
Run Code Online (Sandbox Code Playgroud)

唯一的方法ClassApublic void method(Number n),这就是编译器选择的方法.请记住,这里预期的参数类型是Number,但传递的实际参数(整数3)是自动装入类型的Integer.它起作用的原因是因为方法参数在Java中是协变的.

现在,我认为它打印的原因很明显

ClassA:3类java.lang.Integer


jrd*_*rd1 10

您的问题源于这样的事实(引自官方Java继承的教程):

在子类中,您可以重载从超类继承的方法.这样的重载方法既不隐藏也不重写超类方法 - 它们是新方法,对于子类来说是唯一的

有关更多详细信息,请参阅官方Java教程:http: //docs.oracle.com/javase/tutorial/java/IandI/override.html


Cid*_*Cid 6

a是ClassA类型,因此ClassB中的方法对于实例a是不可见的,除非它被声明为ClassB

ClassB a = new ClassB(); 
Run Code Online (Sandbox Code Playgroud)

将产生您的预期输出.Number是Integer的超类型.因此,无论您传入的是什么,都会被自动装箱到适当的子类型,并且将调用ClassA中的方法.尝试传球

a.method(3.0f) // Float
a.method(3.0) // Double
Run Code Online (Sandbox Code Playgroud)