Java 的多态和方法重载
先看一段代码,他会输出什么:
java
class A {
public void f(){
System.out.println("A.f()");
}
}
class B extends A{
public void f(){
System.out.println("B.f()");
}
}
class C{
public void g(A a){
System.out.print("g(A a) ");
a.f();
}
public void g(B b){
System.out.print("g(B b) ");
b.f();
}
}
public class Main {
public static void main(String[] args) {
C c = new C();
A e = new B();
c.g(e);
}
}
A. g(A a) A.f() B. g(A a) B.f() C. g(B b) A.f() D. g(B b) B.f()
答案是B,输出了g(A a) B.f()
。
这是Java的多态性和方法重载的特性在起作用。
首先,创建了一个B
类的对象,并将其引用类型设为A类(A e = new B();
)。这是Java的多态性的一个例子,即子类对象可以当作父类对象来处理。
然后,调用了C
类的g
方法(c.g(e);
)。根据Java的方法重载规则,编译器会在编译时期根据参数的静态类型(也就是引用类型)来决定调用哪个版本的g方法。因为你的e变量的引用类型是A类,所以编译器选择了g(A a)
这个版本的方法。
在g(A a)
方法中,又调用了a.f()
。这时,Java的动态绑定(也称为后期绑定或运行时绑定)机制起作用了。动态绑定意味着在运行时期,根据对象的实际类型(也就是new操作符后面的类型)来决定调用哪个版本的方法。因为你的e
变量实际指向的是一个B
类的对象,所以这里调用了B
类的f
方法,输出了B.f()
。
所以,整个过程中,g(A a)
是由于方法重载在编译时期的静态绑定结果,而B.f()
是由于多态性在运行时期的动态绑定结果。