日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java 抽象类语法_JAVA基础语法8--多态/抽象类/抽象方法

發(fā)布時間:2023/12/10 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 抽象类语法_JAVA基础语法8--多态/抽象类/抽象方法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

多態(tài)

繼承、封裝、多態(tài)、抽象是面向?qū)ο缶幊痰乃拇蠡咎卣?。封裝隱藏了類的內(nèi)部實現(xiàn)機制,從而可以在不影響使用者的前提條件下,改變類的內(nèi)部結(jié)構(gòu),同時保護了數(shù)據(jù)。繼承是為了重用父類代碼,同時為多態(tài)做準(zhǔn)備。那么,什么是多態(tài)呢?

所謂多態(tài),英文單詞為polymorphism,這個英文單詞是由單詞poly(意思是很多或多個)和morph(意思是形狀或形式)組成的復(fù)合詞。多態(tài)一詞最早出現(xiàn)在生物學(xué),是指生物學(xué)的一個基本原則:一個生物或物種可以有多種不同的形式或階段。面向?qū)ο缶幊涛樟诉@一原則,在OOP中,多態(tài)是指一個對象有多種形式的能力。一個類的子類可以定義它們唯一的行為,同時共享父類的某些相同特征。

多態(tài)可以說是面向?qū)ο缶幊痰木杷凇R虼?#xff0c;理解多態(tài)的含義,對理解面向?qū)ο缶幊逃刑貏e重要的意義。

Java之所以引入多態(tài)的概念,原因之一是它在類的繼承問題上和C++不同。C++允許多繼承,這確實給它帶來了非常強大的功能,但是復(fù)雜的繼承關(guān)系也給C++開發(fā)者帶來了更大的麻煩。為了規(guī)避風(fēng)險,Java只允許單繼承,子類與父類間有IS-A的關(guān)系。這樣做雖然保證了繼承關(guān)系的簡單明了,但是勢必在功能上有很大的限制。所以,Java引入了多態(tài)性的概念,以彌補這點的不足。此外,我們在本節(jié)后面要學(xué)到的抽象類和接口也是解決單繼承規(guī)定限制的重要手段。

在Java中,多態(tài)有兩種理解方式:第一種是對象的不同的方法可以用相同的一個方法名,也就是重載的概念。?另一種是同一對象根據(jù)不同的消息執(zhí)行相應(yīng)的行為,也可以這樣認為發(fā)送消息給某一個對象,讓對象自行選擇哪種相應(yīng)的行為。根據(jù)這種兩種方式,所以多態(tài)可以分為靜態(tài)多態(tài)和動態(tài)多態(tài)。

靜態(tài)多態(tài)指的是程序在編譯時,系統(tǒng)就能決定調(diào)用哪個方法,所以也稱為編譯時多態(tài)。在Java中,靜態(tài)多態(tài)實現(xiàn)的方式就是方法重載,其調(diào)用規(guī)則是依據(jù)對象在定義時的類型相應(yīng)地調(diào)用對應(yīng)類中的重載方法。

動態(tài)多態(tài)指在運行中系統(tǒng)才能動態(tài)確定方法所指的對象,所以也稱為運行時多態(tài)。動態(tài)多態(tài)的實現(xiàn)方式是重寫父類中的同名成員方法,其調(diào)用規(guī)則是依據(jù)對象在實例化時而非定義時的類型,相應(yīng)地調(diào)用對應(yīng)類中的同名成員方法。也就是說,動態(tài)多態(tài)主要通過動態(tài)綁定和重寫的機制來實現(xiàn)。

多態(tài)技術(shù)基礎(chǔ)

在Java中,使用動態(tài)綁定和重寫機制來實現(xiàn)多態(tài),我們首先需要掌握如下三個基礎(chǔ)技術(shù)概念:

向上轉(zhuǎn)型技術(shù):一個父類的引用變量可以指向不同的子類對象,或者說一個子對象可以被當(dāng)作一個父類類型。

instanceof關(guān)鍵字:instanceof關(guān)鍵字用于判斷運行時對象的真正類型。

可以規(guī)避掉“強制向下轉(zhuǎn)型過程中”可能會出現(xiàn)的轉(zhuǎn)型風(fēng)險。

動態(tài)綁定技術(shù):運行時根據(jù)父類引用變量所指對象的實際類型執(zhí)行相應(yīng)的子類方法,從而實現(xiàn)多態(tài)性。

1)向上轉(zhuǎn)型和向下轉(zhuǎn)型

在基礎(chǔ)數(shù)據(jù)類型中,我們已經(jīng)看到了表達式中數(shù)值數(shù)據(jù)類型byte、short、int、long、float和double的相互轉(zhuǎn)換規(guī)則,即:當(dāng)從低精度數(shù)據(jù)類型向高精度數(shù)據(jù)類型轉(zhuǎn)換時實行自動轉(zhuǎn)換,這種類型轉(zhuǎn)換技術(shù)稱為向上轉(zhuǎn)型;當(dāng)從高精度數(shù)據(jù)類型向低精度數(shù)據(jù)類型轉(zhuǎn)換時,需要使用強制類型轉(zhuǎn)換符,這種類型轉(zhuǎn)換技術(shù)稱為向下轉(zhuǎn)型。

對于引用數(shù)據(jù)類型,這種轉(zhuǎn)換技術(shù)依然適用。在父類和子類的繼承層次關(guān)系中,沿著子類向父類向上轉(zhuǎn)型是自動轉(zhuǎn)換,而從父類向子類必須使用強制類型轉(zhuǎn)換才能實現(xiàn)向下轉(zhuǎn)型。

例如:Employee e = new Salary("王二", "勝利大道24號", 47, 250000.00);

這里Salary是Employee的子類

那么,我們?yōu)槭裁匆靡粋€父類類型的引用去指向一個子類的對象呢?為什么不直接用一個子類類型的引用呢?這樣做到底有什么意義呢?

這是因為子類是對父類的一個改進和擴充,所以一般子類在功能上較父類更強大,屬性較父類更獨特。定義一個父類類型的引用指向一個子類的對象,既可以使用子類強大的功能,又可以抽取父類的共性,從而可以使代碼更容易編寫,更容易維護。

既然父類類型的引用沒有改變什么,那么為什么不總是用它呢?如果我們使用Employee類型的引用來指向一個Salary對象,對象不會丟失數(shù)據(jù),但是用父類類型的引用則不能直接訪問Salary類的成員變量和方法的。

如果要用父類類型的引用訪問子類的成員變量和方法,我們就必須將Employee類型的引用強制轉(zhuǎn)換為Salary類型的引用。

如:Salary?salary =(Salary)e;

注:引用數(shù)據(jù)類型向下強制轉(zhuǎn)換是有風(fēng)險的,不一定能夠轉(zhuǎn)型成功,如果要轉(zhuǎn)型成功,必須同時滿足以下兩個要求:

必須是父類引用指向一個子類的實現(xiàn)

強制轉(zhuǎn)換類型必須跟這個子類實現(xiàn)具體的類型一致,不能是父類其他子類的類型

使用instanceof關(guān)鍵字判斷對象的真正類型

Java語言的多態(tài)機制導(dǎo)致了引用變量的聲明類型和實際引用對象的類型可能不一致。為更準(zhǔn)確鑒別一個對象的真正類型,Java語言引入了instanceof運算符。

使用instanceof的語句如下:

引用?instanceof 類名

如果引用是指定的類類型,那么instanceof運算符返回true,否則返回false。

動態(tài)綁定技術(shù)

我們首先要理解Java中的動態(tài)綁定機制。

在面向?qū)ο蟪绦蜷_發(fā)中,我們將一個方法調(diào)用與該方法所在的類關(guān)聯(lián)起來,稱為"綁定"。綁定分靜態(tài)綁定和動態(tài)綁定,或者稱為前期綁定和后期綁定。

所謂靜態(tài)綁定,是指在程序執(zhí)行前方法已經(jīng)被綁定,此時由編譯器或其它連接程序?qū)崿F(xiàn)。針對Java簡單的可以理解為程序編譯期的綁定;這里特別說明一點,Java中的方法只有final、static、private和構(gòu)造器是前期綁定。

所謂動態(tài)綁定,是指在運行時根據(jù)具體對象的類型進行綁定。Java中所有的普通方法,都采用動態(tài)綁定技術(shù)。通過動態(tài)綁定,JVM必須沿著繼承層次樹向下找,判斷一個方法是否被重寫。如果方法被重寫了,在運行時就執(zhí)行子類中的方法,而不是編譯時調(diào)用的父類方法。

多態(tài)的主要應(yīng)用

1)多態(tài)參數(shù)

所謂多態(tài)參數(shù),就是當(dāng)方法的某個形式參數(shù)是一個引用的時候,與該引用兼容的任何對象都可以傳遞給方法,從而允許方法接受不同數(shù)據(jù)類型的形式參數(shù)。

例如,如下的方法有一個Employee類型的形式參數(shù):

public void payEmployee(Employee e)

如果要調(diào)用payEmployee()方法,我們需要用一個Employee對象作為實際參數(shù)。如果Salary和Hourly繼承自Employee類,那么Salary或Hourly對象也可以作為實際參數(shù)傳給payEmployee()方法。因為通過多態(tài),Salary或Hourly對象也是一個Employee對象。

現(xiàn)在,通過將Employee類型的引用作為形式參數(shù),使payEmployee()成為了一個更通用的方法?,F(xiàn)在,它可以接受Employee、Hourly、Salary對象作為實際參數(shù)。如果出現(xiàn)了一個繼承自Employee類的新類,那么這個新類也可以傳遞給payEmplyee()。

2)異構(gòu)集合

多態(tài)最常見的應(yīng)用是創(chuàng)建一個不是同一類型,但是有共同父類的數(shù)據(jù)集合。不同對象的集合稱為異構(gòu)集合。

例如所有的類都繼承object,如果寫一個數(shù)組為object類型數(shù)組,那么就可以裝任何的類型對象。

多態(tài)總結(jié)

從以上示例,我們可以看出:父類類型的引用可以調(diào)用父類中定義的所有屬性和方法,而對于子類中定義而父類中沒有的方法,它是無可奈何的;同時,父類中的一個方法只有在父類中定義而在子類中沒有重寫的情況下,才可以被父類類型的引用調(diào)用;對于父類中定義的方法,如果子類中重寫了該方法,那么父類類型的引用將會調(diào)用子類中的這個方法,這就是動態(tài)綁定。也就是說:在多態(tài)機制中,是由被引用對象的類型,而不是引用變量的類型,決定了調(diào)用誰的成員方法。但是,這個被調(diào)用的方法必須是在父類中定義過的,也就是說被子類重寫的方法?。

因此,對于多態(tài),我們可以總結(jié)它為:

使用父類類型的引用指向子類的對象。

該引用只能調(diào)用父類中定義的方法,不能調(diào)用子類中獨有的方法。

如果子類中重寫了父類中的一個方法,那么在調(diào)用這個方法的時候,將會調(diào)用子類中的這個方法。

在多態(tài)中,子類可以調(diào)用父類中的所有方法。

在Java中,所有普通方法默認都是動態(tài)綁定,要避免動態(tài)綁定默認行為的唯一方法是將方法聲明為final。聲明為final的方法不能被重寫,所以JVM不需要沿著繼承層次樹向下尋找,并試圖判斷子類是否重寫該方法?;诖嗽?#xff0c;final方法可以提升性能,因為避免了動態(tài)綁定的開銷。

抽象

我們在編寫類時,通常會在類中定義一些方法,用來描述該類所具有的行為。在類的方法體中,我們編寫代碼實現(xiàn)該類所要執(zhí)行的行為。在繼承關(guān)系中,子類繼承父類后,子類也就具有父類所具備的行為。如果子類繼承了父類的行為,但是與父類的行為實現(xiàn)方式不同,就需要通過方法重寫來覆蓋父類的行為。

如果我們不需要類的實例時,就可以將類設(shè)計成為一個抽象類。所謂抽象類,是不能被實例化的類。在抽象類中,類的所有其它功能都存在,成員變量、方法、構(gòu)造器都可以用同樣的方式訪問。我們只是不能創(chuàng)建抽象類的實例。

抽象類

在Java中,使用關(guān)鍵字abstract可以聲明一個抽象類,該關(guān)鍵字可以出現(xiàn)在類聲明時class關(guān)鍵字前的任何地方。

我們注意到類除了聲明為abstract外,其它的沒有改變?,F(xiàn)在,我們不能實例化一個抽象的對象。但是對于它的子類沒有任何影響。

抽象方法

在父類中有的行為我們不需要去具體實現(xiàn),因為我們永遠不會調(diào)用它,但是它又是子類必須有的,我們只需要在子類中去對方法進行重寫,進行具體的實現(xiàn)。這種情況下,我們就可以用抽象方法了。如果我們想一個類包含一個特定的方法,該方法的實際實現(xiàn)由子類決定,那么我們就可以在父類中將該方法聲明為抽象方法。抽象方法只有方法簽名,沒有方法體。

代碼清單展示了聲明為抽象的computePay()方法。注意,該方法沒有定義部分,并且方法簽名后跟一個分號,沒有大括號。

/*代碼清單??Employee.java

這里,computePay()方法被聲明為抽象方法,在類中沒有實現(xiàn)

*/

public abstract class Employee{

private String name;

private String address;

private int number;

public abstract double computePay();

//類定義的剩余部分

}

將一個方法聲明為抽象方法有兩個結(jié)果:

類也必須聲明為抽象類。如果一個類包含了抽象方法,那么該類也必須是抽象的。

任何子類必須重寫抽象方法,除非子類本身也是抽象的。

從設(shè)計的角度看,將一個抽象方法放在父類中,可以強制任何子類實現(xiàn)一個特別的行為。繼承抽象方法的子類必須重寫該方法。如果子類不重寫抽象方法,那么子類必須是抽象類,子類的子類必須重寫該方法。最終,必須有一個后代類實現(xiàn)抽象方法,否則,我們就有一個不能實例化的抽象類層次。

那么,為什么要使用方法抽象呢?這是因為強制其它類實現(xiàn)某個行為有好處。

使用抽象類類和抽象方法的好處

用抽象類及接口最重要的用處還是在于,使代碼實現(xiàn)很方便的擴展,最簡單的就是在new對象時,將生成對象定義為接口,在以后需要替換時就很方便。

抽象類及接口,并不只是為了抽象,為了接口面抽象,而接口。在你需要用到一系列可繼承自抽象類的子類,或是需要實現(xiàn)共同接口的多個實現(xiàn)類時,才需要考慮。

其實抽象類的一個好處是類不能被實例化,最大的好處就是通過方法的覆蓋來實現(xiàn)多態(tài)的屬性。也就是運行期綁定。

用抽象的型別統(tǒng)一類型,來進行操作,有利于以后的擴展,移植,復(fù)用!!

總結(jié)

以上是生活随笔為你收集整理的java 抽象类语法_JAVA基础语法8--多态/抽象类/抽象方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产精品自产拍高潮在线观看 | 亚州 | 琪琪原网址 | 青青草欧美 | 欧美中文字幕一区 | 亚洲人无码成www久久 | 国产综合久久 | 久草福利资源在线观看 | 涩涩天堂 | 狂野欧美性猛交xxⅹ李丽珍 | 人人爽久久涩噜噜噜网站 | 天堂亚洲网 | 中文字幕在线免费看 | 欧美区亚洲区 | 天天综合在线观看 | 在线a视频| 波多野结衣在线观看一区 | 久久国产精品久久精品国产 | 国产精品入口66mio男同 | 国产又大又黄又爽 | av福利网站 | 成人免费网站在线 | 久久久久久国产精品免费播放 | 台湾佬美性中文娱乐 | 国产男女在线 | 国产一级aa大片毛片 | 久久免费黄色 | 日本成人久久 | 国产一二三区在线视频 | 中国老妇性视频 | 久久av导航 | 岛国av免费观看 | 丁香花高清在线 | 欧美激情亚洲色图 | 91久久久久久久久久 | 欧美人妻少妇一区二区三区 | 国产三级播放 | 91成年人网站 | 国产高潮呻吟久久 | 91大神在线观看视频 | 亚洲成人免费在线视频 | 成人免费视频一区 | 欧美区亚洲区 | 成人宗合网 | 天天色天天干天天 | 日韩福利视频 | 亚洲wwww| 99精品视频网站 | 秘密爱大尺度做爰呻吟 | 亚洲精品日韩在线观看 | 三上悠亚 在线观看 | 欧美性欧美zzzzzzzzz | 亚洲精品三区 | 成 人 黄 色 片 在线播放 | 91文字幕巨乱亚洲香蕉 | 色眯眯影视 | 亚洲第一综合网 | 男人天堂a在线 | 日韩欧美国产视频 | 成人午夜激情网 | 黄色一级视频免费观看 | 国模私拍在线 | 91蝌蚪91九色 | 欧美黄色大片网站 | 强行挺进白丝老师里呻吟 | 日本三区在线 | 男女扒开双腿猛进入爽爽免费 | 国内成人av | 少妇又色又爽又高潮极品 | 一级a性色生活片久久毛片 爱爱高潮视频 | 久久99日| 一级做a爰片久久毛片 | 成人福利在线 | 国产a一级片 | 毛片在线观看网站 | 99re在线视频 | 香蕉久久国产av一区二区 | 亚洲最大福利网 | 操xxxx| 精品无码久久久久久久久成人 | 欧美系列第一页 | 日韩毛片大全 | 中文字幕久久一区 | 成人午夜av在线 | 69xxxx国产| 三级av| 中文字幕亚洲欧美 | 亚洲欧美视频在线 | 久久精品99国产精品日本 | 日本一区免费视频 | 美日韩av| 久久亚洲AV无码 | 99国产精品白浆在线观看免费 | 97久久综合| 日本精品人妻无码免费大全 | 日韩女同一区二区三区 | 久久嫩草视频 | 久久久久久久99 | 国产精品人人妻人人爽人人牛 |