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,以及ClassB的method()有一个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)
唯一的方法ClassA是public 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
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)
| 归档时间: |
|
| 查看次数: |
9415 次 |
| 最近记录: |