運(yùn)行時(shí)多態(tài)性是面向?qū)ο蟪绦蛟O(shè)計(jì)代碼重用的一個(gè)最強(qiáng)大機(jī)制,動(dòng)態(tài)性的概念也可以被說成“一個(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)。 一、通過繼承中超類對(duì)象引用變量引用子類對(duì)象來實(shí)現(xiàn) 舉例說明: //定義超類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,通過將子類對(duì)象引用賦值給超類對(duì)象引用變量來實(shí)現(xiàn)動(dòng)態(tài)方法調(diào)用。也許有人會(huì)問:“為什么(1)和(2)不輸出:This is superA”。java 的這種機(jī)制遵循一個(gè)原則:當(dāng)超類對(duì)象引用變量引用子類對(duì)象時(shí),被引用對(duì)象的類型而不是引用變量的類型決定了調(diào)用誰的成員方法,但是這個(gè)被調(diào)用的方法必須是在超類中定義過的,也就是說被子類覆蓋的方法。 所以,不要被上例中(1)和(2)所迷惑,雖然寫成a.fun(),但是由于(1)中的a被b賦值,指向了子類subB的一個(gè)實(shí)例,因而(1)所調(diào)用的fun()實(shí)際上是子類subB的成員方法fun(),它覆蓋了超類superA的成員方法fun();同樣(2)調(diào)用的是子類subC的成員方法fun()。 另外,如果子類繼承的超類是一個(gè)抽象類,雖然抽象類不能通過new操作符實(shí)例化,但是可以創(chuàng)建抽象類的對(duì)象引用指向子類對(duì)象,以實(shí)現(xiàn)運(yùn)行時(shí)多態(tài)性。具體的實(shí)現(xiàn)方法同上例。 不過,抽象類的子類必須覆蓋實(shí)現(xiàn)超類中的所有的抽象方法,否則子類必須被abstract修飾符修飾,當(dāng)然也就不能被實(shí)例化了。 二、通過接口類型變量引用實(shí)現(xiàn)接口的類的對(duì)象來實(shí)現(xiàn) 接口的靈活性就在于“規(guī)定一個(gè)類必須做什么,而不管你如何做”。我們可以定義一個(gè)接口類型的引用變量來引用實(shí)現(xiàn)接口的類的實(shí)例,當(dāng)這個(gè)引用調(diào)用方法時(shí),它會(huì)根據(jù)實(shí)際引用的類的實(shí)例來判斷具體調(diào)用哪個(gè)方法,這和上述的超類對(duì)象引用訪問子類對(duì)象的機(jī)制相似。 舉例說明: //定義接口InterA interface InterA { void fun(); } //實(shí)現(xiàn)接口InterA的類B class B implements InterA { public void fun() { System.out.println(“This is B”); } } //實(shí)現(xiàn)接口InterA的類C class C implements InterA { public void fun() { System.out.println(“This is C”); } } class Test { public static void main(String[] args) { InterA a; a= new B(); a.fun(); a = new C(); a.fun(); } } 輸出結(jié)果為: This is B This is C 上例中類B和類C是實(shí)現(xiàn)接口InterA的兩個(gè)類,分別實(shí)現(xiàn)了接口的方法fun(),通過將類B和類C的實(shí)例賦給接口引用a而實(shí)現(xiàn)了方法在運(yùn)行時(shí)的動(dòng)態(tài)綁定,充分利用了“一個(gè)接口,多個(gè)方法”展示了Java的動(dòng)態(tài)多態(tài)性。 需要注意的一點(diǎn)是:Java在利用接口變量調(diào)用其實(shí)現(xiàn)類的對(duì)象的方法時(shí),該方法必須已經(jīng)在接口中被聲明,而且在接口的實(shí)現(xiàn)類中該實(shí)現(xiàn)方法的類型和參數(shù)必須與接口中所定義的精確匹配。 結(jié)束語:以上就是java運(yùn)行時(shí)多態(tài)性的實(shí)現(xiàn)方法,大家在編程過程中可以靈活運(yùn)用,但是在性能要求較高的代碼中不提倡運(yùn)用運(yùn)行時(shí)多態(tài),畢竟Java的運(yùn)行時(shí)動(dòng)態(tài)方法調(diào)用較之普通的方法調(diào)用的系統(tǒng)開銷是比較大的。
創(chuàng)新互聯(lián)建站專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、花都網(wǎng)絡(luò)推廣、微信小程序定制開發(fā)、花都網(wǎng)絡(luò)營(yíng)銷、花都企業(yè)策劃、花都品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)建站為所有大學(xué)生創(chuàng)業(yè)者提供花都建站搭建服務(wù),24小時(shí)服務(wù)熱線:13518219792,官方網(wǎng)址:chinadenli.net
第一步:創(chuàng)建一個(gè)父類,如Animal(動(dòng)物) 類,這個(gè)方法中只有方法的定義,沒有實(shí)現(xiàn)。第二步:創(chuàng)建一個(gè)子類,如cat(貓)類,這個(gè)方法中實(shí)現(xiàn)父類中的所有方法,并進(jìn)行重寫。
第三步:創(chuàng)建一個(gè)子類,如dog(狗)類,這個(gè)方法中實(shí)現(xiàn)父類中的所有方法,并進(jìn)行重寫。
備注:多態(tài)實(shí)際上是一個(gè)父類有特定的屬性,如動(dòng)物有名稱、年齡、所屬科目,之后由子類去實(shí)現(xiàn)具體的,如貓,名稱是貓,年齡是5歲,所屬科目為貓科,然后狗同樣有這些屬性,只不過是值不同,這個(gè)就是一個(gè)多態(tài)的形式。子類可以有無限多,在步驟三后面添加即可。
有一個(gè)比較經(jīng)典的多態(tài)實(shí)例:
有一個(gè)Animal類,它有Cat,和Dog兩個(gè)子類,在Animal中有個(gè)say方法,當(dāng)Cat調(diào)用這個(gè)方法的時(shí)候輸出的是“小貓喵喵喵”,當(dāng)Dog調(diào)用這個(gè)方法時(shí),輸出的是“小狗汪汪汪”,這就是Java多態(tài)的實(shí)現(xiàn)。
1、定義一種動(dòng)物,該類型的動(dòng)物有叫的屬性。
2、分別定義貓,狗,鳥,都繼承于該動(dòng)物,都有叫的屬性。
3、分別表示出各個(gè)具體小動(dòng)物的叫聲,例如貓的叫聲:喵、狗的叫聲:汪、鳥的叫聲:咻,點(diǎn)是叫聲,實(shí)現(xiàn)各個(gè)具體小動(dòng)物用的叫聲的方法是用的同一個(gè)函數(shù)名稱,就是動(dòng)物的叫聲函數(shù)。
多態(tài):
這個(gè)案例網(wǎng)上是沒有的,屬于無忌獨(dú)創(chuàng),當(dāng)時(shí)在幫孩子輔導(dǎo)作業(yè),小學(xué)科學(xué),里面有一點(diǎn)內(nèi)容是關(guān)于人的牙齒,說牙齒分為:門齒、犬齒、臼齒。
問閨女,為什么這么分呢?閨女說牙齒雖然都是用來咬食物,但是食物種類很多,咬碎需要的工具也不一樣,門齒用來切割食物,如:蘋果、梨;犬齒用來撕碎食物。
如肉類;臼齒用來磨碎食物,如犬齒撕碎的肉類,就需要再用臼齒來磨碎,然后送到食道,胃,小腸,大腸進(jìn)行消化。我恍然大悟,這不就是Java面向?qū)ο罄锏亩鄳B(tài)嗎?多完美啊。
這也很好說明了為什么會(huì)有多態(tài)出現(xiàn),因?yàn)樯钪芯痛嬖谔噙@種例子,所以需要多態(tài)來匹配解決。
什么是多態(tài)
面向?qū)ο蟮娜筇匦裕悍庋b、繼承、多態(tài)。從一定角度來看,封裝和繼承幾乎都是為多態(tài)而準(zhǔn)備的。這是我們最后一個(gè)概念,也是最重要的知識(shí)點(diǎn)。
多態(tài)的定義:指允許不同類的對(duì)象對(duì)同一消息做出響應(yīng)。即同一消息可以根據(jù)發(fā)送對(duì)象的不同而采用多種不同的行為方式。(發(fā)送消息就是函數(shù)調(diào)用)
實(shí)現(xiàn)多態(tài)的技術(shù)稱為:動(dòng)態(tài)綁定(dynamic binding),是指在執(zhí)行期間判斷所引用對(duì)象的實(shí)際類型,根據(jù)其實(shí)際的類型調(diào)用其相應(yīng)的方法。
多態(tài)的作用:消除類型之間的耦合關(guān)系。
現(xiàn)實(shí)中,關(guān)于多態(tài)的例子不勝枚舉。比方說按下 F1 鍵這個(gè)動(dòng)作,如果當(dāng)前在 Flash 界面下彈出的就是 AS 3 的幫助文檔;如果當(dāng)前在 Word 下彈出的就是 Word 幫助;在 Windows 下彈出的就是 Windows 幫助和支持。同一個(gè)事件發(fā)生在不同的對(duì)象上會(huì)產(chǎn)生不同的結(jié)果。
--------------------------
再簡(jiǎn)單一點(diǎn):坐公車時(shí),一個(gè)男的靠在你的肩膀,你可能不爽,但是如果一個(gè)美女靠在你的肩膀你就很樂意,這就是多態(tài)的表現(xiàn)
這是java的特征,運(yùn)行起來沒有啥條件,只是看你會(huì)不會(huì)用,給你個(gè)簡(jiǎn)單的例子:
class A{
method(){
System.out.println("a");}
}
class B extends A{
method(){
System.out.println("b");
}}
class test{
main(){
A test = new B();
test.method();//執(zhí)行以后輸出的是:b。解釋就是:父類引用(A)指向子類對(duì)象(B),這個(gè)引用調(diào)用的是子類的方法,而不是父類A的方法;
}}
繼承實(shí)現(xiàn)多態(tài)其實(shí)原理類似:
interface A{
method();}
class B implements A{
method(){
System.out.println();}}
class test{
main(){
A test = new B();
test.method();//此處便會(huì)使用java的多態(tài),B實(shí)現(xiàn)了A,雖然=前面是A test,但實(shí)際上生成的確是B的對(duì)象,所以調(diào)用它的方法,同繼承中的父類對(duì)象指向子類對(duì)象原理相同,只是此處為繼承;
}}
運(yùn)行時(shí)多態(tài)性是面向?qū)ο蟪绦蛟O(shè)計(jì)代碼重用的一個(gè)最強(qiáng)大機(jī)制 動(dòng)態(tài)性的概念也可以被說成 一個(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)
一 通過繼承中超類對(duì)象引用變量引用子類對(duì)象來實(shí)現(xiàn)
舉例說明
//定義超類superA
class superA
{
int i =
void fun()
{
System out println( This is superA )
}
}
//定義superA的子類subB
class subB extends superA
{
int m =
void fun()
{
System out println( This is subB )
}
}
//定義superA的子類subC
class subC extends superA
{
int n =
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() ???????? ( )
a=c
a fun() ???????? ( )
}
}
運(yùn)行結(jié)果為
This is subB
This is subC
上述代碼中subB和subC是超類superA的子類 我們?cè)陬怲est中聲明了 個(gè)引用變量a b c 通過將子類對(duì)象引用賦值給超類對(duì)象引用變量來實(shí)現(xiàn)動(dòng)態(tài)方法調(diào)用 也許有人會(huì)問 為什么( )和( )不輸出 This is superA java 的這種機(jī)制遵循一個(gè)原則 當(dāng)超類對(duì)象引用變量引用子類對(duì)象時(shí) 被引用對(duì)象的類型而不是引用變量的類型決定了調(diào)用誰的成員方法 但是這個(gè)被調(diào)用的方法必須是在超類中定義過的 也就是說被子類覆蓋的方法
所以 不要被上例中( )和( )所迷惑 雖然寫成a fun() 但是由于( )中的a被b賦值 指向了子類subB的一個(gè)實(shí)例 因而( )所調(diào)用的fun()實(shí)際上是子類subB的成員方法fun() 它覆蓋了超類superA的成員方法fun() 同樣( )調(diào)用的是子類subC的成員方法fun()
另外 如果子類繼承的超類是一個(gè)抽象類 雖然抽象類不能通過new操作符實(shí)例化 但是可以創(chuàng)建抽象類的對(duì)象引用指向子類對(duì)象 以實(shí)現(xiàn)運(yùn)行時(shí)多態(tài)性 具體的實(shí)現(xiàn)方法同上例
不過 抽象類的子類必須覆蓋實(shí)現(xiàn)超類中的所有的抽象方法 否則子類必須被abstract修飾符修飾 當(dāng)然也就不能被實(shí)例化了
二 通過接口類型變量引用實(shí)現(xiàn)接口的類的對(duì)象來實(shí)現(xiàn)
接口的靈活性就在于 規(guī)定一個(gè)類必須做什么 而不管你如何做 我們可以定義一個(gè)接口類型的引用變量來引用實(shí)現(xiàn)接口的類的實(shí)例 當(dāng)這個(gè)引用調(diào)用方法時(shí) 它會(huì)根據(jù)實(shí)際引用的類的實(shí)例來判斷具體調(diào)用哪個(gè)方法 這和上述的超類對(duì)象引用訪問子類對(duì)象的機(jī)制相似
舉例說明
//定義接口InterA
interface InterA
{
void fun()
}
//實(shí)現(xiàn)接口InterA的類B
class B implements InterA
{
public void fun()
{
System out println( This is B )
}
}
//實(shí)現(xiàn)接口InterA的類C
class C implements InterA
{
public void fun()
{
System out println( This is C )
}
}
class Test
{
public static void main(String[] args)
{
InterA a
a= new B()
a fun()
a = new C()
a fun()
}
}
輸出結(jié)果為
This is B
This is C
上例中類B和類C是實(shí)現(xiàn)接口InterA的兩個(gè)類 分別實(shí)現(xiàn)了接口的方法fun() 通過將類B和類C的實(shí)例賦給接口引用a而實(shí)現(xiàn)了方法在運(yùn)行時(shí)的動(dòng)態(tài)綁定 充分利用了 一個(gè)接口 多個(gè)方法 展示了Java的動(dòng)態(tài)多態(tài)性
需要注意的一點(diǎn)是 Java在利用接口變量調(diào)用其實(shí)現(xiàn)類的對(duì)象的方法時(shí) 該方法必須已經(jīng)在接口中被聲明 而且在接口的實(shí)現(xiàn)類中該實(shí)現(xiàn)方法的類型和參數(shù)必須與接口中所定義的精確匹配
lishixinzhi/Article/program/Java/hx/201311/26085
網(wǎng)站標(biāo)題:代碼演示java多態(tài) java程序如何實(shí)現(xiàn)多態(tài)
當(dāng)前鏈接:http://chinadenli.net/article6/dodceog.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃、標(biāo)簽優(yōu)化、網(wǎng)站排名、網(wǎng)站收錄、、搜索引擎優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)