运行时多态性是面向对象程序设计代码重用的一个最强大机制,动态性的概念也可以被说成“一个接口,多个方法”。Java实现运行时多态性的基础是动态方法调度,它是一种在运行时而不是在编译期调用重载方法的机制,下面就继承和接口实现两方面谈谈java运行时多态性的实现。 >72zsm
DuQ$*F_Zq
一、通过继承中超类对象引用变量引用子类对象来实现 9||"x&V
;n.<74x
举例说明: 6:ChVb3&0
5"iHZAj
//定义超类superA G%z'h R|
class superA (WC(8H K
{ i)Y mZ}S
int i = 100; ]uxh5BL*
void fun() 8b{%@;(h
{ DQ~GU
System.out.println(“This is superA”); p)z2G ,
} PMJ'0=p
} [V!A=F+pA
//定义superA的子类subB P=jT#6;' +
class subB extends superA Z%0F}i
{ %,O 0+
int m = 1; Ef26 M]]X
void fun() 6MVWPAK
{ L@Og)$
System.out.println(“This is subB”); A.(~"UOQz
} GB<nSX? =
} caF7zbC]U
//定义superA的子类subC o9B
class subC extends superA }x6/p^
{ d#qzu
int n = 1; DH;+-Oo|
void fun() E[}v}WI
{ VO&}tkgj
System.out.println(“This is subC”); YCS{]m8^E
} (0Y`PE'
} ?3W)~61qv
O1>R!-SPc
class Test RJZG.>iE
{ liM@TT
public static void main(String[] args) wZ N:I BI
{ W'X-+kGI
superA a; AV0.i}
subB b = new subB(); 7/Tw:fyr]
subC c = new subC(); : +\%x5
a=b; l[s;g?G
a.fun(); (1) 5!bEgkn
a=c; -JtXr
a.fun(); (2) YE'lyhRR
} ;NrSS'e\,
} u)k16m_-@
Q (9~nR}
运行结果为: FDZ#'w
1Q29mv}
This is subB T|#vV>
This is subC P+zorfV!%
s9'Fh#m'/
上述代码中subB和subC是超类superA的子类,我们在类Test中声明了3个引用变量a, b, c,通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用。也许有人会问:“为什么(1)和(2)不输出:This is superA”。java 的这种机制遵循一个原则:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。 ]=bEdX
QCI+B2b
所以,不要被上例中(1)和(2)所迷惑,虽然写成a.fun(),但是由于(1)中的a被b赋值,指向了子类subB的一个实例,因而(1)所调用的fun()实际上是子类subB的成员方法fun(),它覆盖了超类superA的成员方法fun();同样(2)调用的是子类subC的成员方法fun()。 I26
o\%1$G
另外,如果子类继承的超类是一个抽象类,虽然抽象类不能通过new操作符实例化,但是可以创建抽象类的对象引用指向子类对象,以实现运行时多态性。具体的实现方法同上例。 tNr)@,\r
=0&W"uKzo
不过,抽象类的子类必须覆盖实现超类中的所有的抽象方法,否则子类必须被abstract修饰符修饰,当然也就不能被实例化了。
查看本文来源