📅  最后修改于: 2020-03-19 05:24:48             🧑  作者: Mango
先决条件:继承
方法覆盖是Java支持运行时多态性的方法之一。动态方法Dispatch是一种在运行时而不是编译时解决对覆盖方法的调用机制。
因此,如果超类包含被子类覆盖的方法,则当通过超类引用变量引用不同类型的对象时,将执行该方法的不同版本。这是说明动态方法分派的示例:
// Java程序,利用继承使用动态方法
class A
{
void m1()
{
System.out.println("在A的m1方法内");
}
}
class B extends A
{
// 覆盖m1()
void m1()
{
System.out.println("在B的m1方法内");
}
}
class C extends A
{
// 覆盖m1()
void m1()
{
System.out.println("在C的m1方法内");
}
}
// 测试代码
class Dispatch
{
public static void main(String args[])
{
// A的实例
A a = new A();
// B的实例
B b = new B();
// C的实例
C c = new C();
// A的引用
A ref;
ref = a;
// 调用A的m1()
ref.m1();
// b分配给ref
ref = b;
// 调用B的m1()
ref.m1();
// C分配给ref
ref = c;
// 代用C的m1()
ref.m1();
}
}
输出:
在A的m1方法内
在B的m1方法内
在C的m1方法内
说明:
上面的程序创建了一个名为A的超类,它有B和C的两个子类。这些子类覆盖了m1()方法。
A a = new A(); // A类型实例
B b = new B(); // B类型实例
C c = new C(); // C类型实例
A ref; // A类型的引用
ref = a; // ref指向一个A对象
ref.m1(); // 调用A的m1()版本
ref = b; // ref指向一个b对象
ref.m1(); // 调用B的m1()版本
ref = c; // ref指向一个c对象
ref.m1(); // 调用C的m1()版本
数据成员的运行时多态
在Java中,我们只能覆盖方法,而不能覆盖变量(数据成员),因此数据成员无法实现运行时多态。例如 :
// Java展示成员变量无法完成运行时多态
// class A
class A
{
int x = 10;
}
// class B
class B extends A
{
int x = 20;
}
// 测试代码
public class Test
{
public static void main(String args[])
{
A a = new B(); // B的实例
// A的成员变量将被获取
System.out.println(a.x);
}
}
输出:
10
说明:在上面的程序中,类A(超类)和B(子类)都具有公共变量’x’。现在,我们将类B的对象称为“ a”,它是类A的类型。由于未覆盖成员变量,因此语句“ a.x”将始终引用超类的数据成员。
动态方法分派的优势
静态与动态绑定