姓名: 李小娜
[嵌牛導(dǎo)讀]: ?運(yùn)行時(shí)多態(tài)性是面向?qū)ο蟪绦蛟O(shè)計(jì)代碼重用的一個(gè)最強(qiáng)大機(jī)制啃炸,動(dòng)態(tài)性的概念也可以被說(shuō)成“一個(gè)接口,多個(gè)方法”加派。Java實(shí)現(xiàn)運(yùn)行時(shí)多態(tài)性的基礎(chǔ)是動(dòng)態(tài)方法調(diào)度叫确,它是一種在運(yùn)行時(shí)而不是在編譯期調(diào)用重載方法的機(jī)制,下面就繼承和接口實(shí)現(xiàn)兩方面談?wù)刯ava運(yùn)行時(shí)多態(tài)性的實(shí)現(xiàn)芍锦。
[嵌牛鼻子]:通過(guò)繼承中超類對(duì)象引用變量引用子類對(duì)象來(lái)實(shí)現(xiàn)
[嵌牛提問(wèn)] :如何實(shí)現(xiàn)運(yùn)行時(shí)java的多態(tài)性竹勉?
[嵌牛正文] : ?一、通過(guò)繼承中超類對(duì)象引用變量引用子類對(duì)象來(lái)實(shí)現(xiàn)
舉例說(shuō)明:
//定義超類superA
class superA
{
int i = 100;
void fun()
{
System.out.println(“This is superA”);
}
}
//定義superA的子類subB
class subB extends superA
{
int m = 1;
void fun()
{
System.out.println(“This is subB”);
}
}
//定義superA的子類subC
class subC extends superA
{
int n = 1;
void fun()
{
System.out.println(“This is subC”);
}
}
class Test
{
public static void main(String[] args)
{
superA a;
subB b = new subB();
subC c = new subC();
a=b;
a.fun(); (1)
a=c;
a.fun(); (2)
}
}
運(yùn)行結(jié)果為:
This is subB
This is subC
上述代碼中subB和subC是超類superA的子類娄琉,我們?cè)陬怲est中聲明了3個(gè)引用變量a, b, c次乓,通過(guò)將子類對(duì)象引用賦值給超類對(duì)象引用變量來(lái)實(shí)現(xiàn)動(dòng)態(tài)方法調(diào)用吓歇。也許有人會(huì)問(wèn):“為什么(1)和(2)不輸出:This is superA”。java 的這種機(jī)制遵循一個(gè)原則:當(dāng)超類對(duì)象引用變量引用子類對(duì)象時(shí)票腰,被引用對(duì)象的類型而不是引用變量的類型決定了調(diào)用誰(shuí)的成員方法照瘾,但是這個(gè)被調(diào)用的方法必須是在超類中定義過(guò)的,也就是說(shuō)被子類覆蓋的方法丧慈。
所以析命,不要被上例中(1)和(2)所迷惑,雖然寫(xiě)成a.fun()逃默,但是由于(1)中的a被b賦值鹃愤,指向了子類subB的一個(gè)實(shí)例,因而(1)所調(diào)用的fun()實(shí)際上是子類subB的成員方法fun()完域,它覆蓋了超類superA的成員方法fun()软吐;同樣(2)調(diào)用的是子類subC的成員方法fun()。
另外吟税,如果子類繼承的超類是一個(gè)抽象類凹耙,雖然抽象類不能通過(guò)new操作符實(shí)例化,但是可以創(chuàng)建抽象類的對(duì)象引用指向子類對(duì)象肠仪,以實(shí)現(xiàn)運(yùn)行時(shí)多態(tài)性肖抱。具體的實(shí)現(xiàn)方法同上例。
不過(guò)异旧,抽象類的子類必須覆蓋實(shí)現(xiàn)超類中的所有的抽象方法意述,否則子類必須被abstract修飾符修飾,當(dāng)然也就不能被實(shí)例化了吮蛹。