成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

第3章:抽象數(shù)據(jù)類型(ADT)和面向?qū)ο缶幊蹋∣OP) 3.4面向?qū)ο缶幊蹋∣OP)

Heier / 2489人閱讀

摘要:抽象數(shù)據(jù)類型的多個(gè)不同表示可以共存于同一個(gè)程序中,作為實(shí)現(xiàn)接口的不同類。封裝和信息隱藏信息隱藏將精心設(shè)計(jì)的模塊與不好的模塊區(qū)分開(kāi)來(lái)的唯一最重要的因素是其隱藏內(nèi)部數(shù)據(jù)和其他模塊的其他實(shí)施細(xì)節(jié)的程度。

大綱

面向?qū)ο蟮臉?biāo)準(zhǔn)
基本概念:對(duì)象,類,屬性,方法和接口
OOP的獨(dú)特功能

封裝和信息隱藏
繼承和重寫
多態(tài)性,子類型和重載
靜態(tài)與動(dòng)態(tài)分派

Java中一些重要的Object方法
設(shè)計(jì)好的類
面向?qū)ο蟮臍v史
總結(jié)

面向?qū)ο蟮臉?biāo)準(zhǔn)

面向?qū)ο蟮木幊谭椒?語(yǔ)言應(yīng)該具有類的概念作為中心概念。
語(yǔ)言應(yīng)該能夠?yàn)轭惡退奶卣魈峁嘌裕匆?guī)范:前置條件,后置條件和不變量)和異常處理,依靠工具生成這些斷言中的文檔,并且可選地在運(yùn)行時(shí)監(jiān)視它們 時(shí)間。

他們幫助生產(chǎn)可靠的軟件;

他們提供系統(tǒng)文件;

它們是測(cè)試和調(diào)試面向?qū)ο筌浖暮诵墓ぞ摺?/p>

靜態(tài)類型:一個(gè)定義良好的類型系統(tǒng)應(yīng)該通過(guò)強(qiáng)制執(zhí)行一些類型聲明和兼容性規(guī)則來(lái)保證它接受的系統(tǒng)的運(yùn)行時(shí)類型安全。

泛型(Genericity):用于“準(zhǔn)備改變”和“為/重用設(shè)計(jì)”:應(yīng)該可以編寫具有表示任意類型的正式泛型參數(shù)的類。

繼承(Inheritance):應(yīng)該可以將一個(gè)類定義為從另一個(gè)繼承,以控制潛在的復(fù)雜性。

多態(tài)(Polymorphism):在基于繼承的類型系統(tǒng)的控制下,應(yīng)該可以將實(shí)體(表示運(yùn)行時(shí)對(duì)象的軟件文本中的名稱)附加到各種可能類型的運(yùn)行時(shí)對(duì)象。

動(dòng)態(tài)分派/綁定(Dynamic dispatch / binding):在一個(gè)實(shí)體上調(diào)用一個(gè)特性應(yīng)該總是觸發(fā)與所附加的運(yùn)行時(shí)對(duì)象的類型相對(duì)應(yīng)的特性,這在調(diào)用的不同執(zhí)行過(guò)程中不一定是相同的。

基本概念:對(duì)象,類,屬性和方法

對(duì)象

真實(shí)世界的物體有兩個(gè)特征:它們都有狀態(tài)和行為。
識(shí)別真實(shí)世界對(duì)象的狀態(tài)和行為是從OOP角度開(kāi)始思考的好方法。

狗有狀態(tài)(名稱,顏色,品種,饑餓)和行為(吠叫,取出,搖尾巴)。

自行車具有狀態(tài)(當(dāng)前檔位,當(dāng)前踏板節(jié)奏,當(dāng)前速度)和行為(更換檔位,改變踏板節(jié)奏,應(yīng)用制動(dòng)器)。

對(duì)于你看到的每個(gè)對(duì)象,問(wèn)自己兩個(gè)問(wèn)題,這些現(xiàn)實(shí)世界的觀察都轉(zhuǎn)化為OOP的世界:

這個(gè)物體有什么可能的狀態(tài)?

這個(gè)對(duì)象有什么可能的行為?

一個(gè)對(duì)象是一組狀態(tài)和行為

狀態(tài) - 包含在對(duì)象中的數(shù)據(jù)。

在Java中,這些是對(duì)象的字段

行為 - 對(duì)象支持的操作

在Java中,這些被稱為方法

方法只是面向?qū)ο蟮墓δ?/p>

調(diào)用一個(gè)方法=調(diào)用一個(gè)函數(shù)

每個(gè)對(duì)象都有一個(gè)類

一個(gè)類定義方法和字段

統(tǒng)稱為成員的方法和領(lǐng)域

類定義了類型和實(shí)現(xiàn)

類型≈可以使用對(duì)象的位置

執(zhí)行≈對(duì)象如何做事情

松散地說(shuō),類的方法是它的應(yīng)用程序編程接口(API)

定義用戶如何與實(shí)例進(jìn)行交互

靜態(tài)與實(shí)例變量/類的方法

類成員變量:與類相關(guān)聯(lián)的變量,而不是類的實(shí)例。 您還可以將方法與類關(guān)聯(lián) - 類方法。

要引用類變量和方法,需要將類的名稱和類方法或類變量的名稱連同句點(diǎn)(".")一起加入。

不是類方法或類變量的方法和變量稱為實(shí)例方法和實(shí)例成員變量。

要引用實(shí)例方法和變量,必須引用類實(shí)例中的方法和變量

總結(jié):

類變量和類方法與類相關(guān)聯(lián),并且每個(gè)類都會(huì)出現(xiàn)一次。 使用它們不需要?jiǎng)?chuàng)建對(duì)象。

實(shí)例方法和變量在類的每個(gè)實(shí)例中出現(xiàn)一次。

靜態(tài)方法不與任何特定的類實(shí)例關(guān)聯(lián),而實(shí)例方法(不帶static關(guān)鍵字聲明)必須在特定對(duì)象上調(diào)用。

接口

Java的接口是一種用于設(shè)計(jì)和表達(dá)ADT的有用語(yǔ)言機(jī)制,其實(shí)現(xiàn)方式是實(shí)現(xiàn)該接口的類。

Java中的接口是方法簽名的列表,但沒(méi)有方法體。

如果一個(gè)類在其implements子句中聲明接口并為所有接口的方法提供方法體,則該類將實(shí)現(xiàn)一個(gè)接口。

一個(gè)接口可以擴(kuò)展一個(gè)或多個(gè)其他接口

一個(gè)類可以實(shí)現(xiàn)多個(gè)接口

接口和類:定義和實(shí)現(xiàn)ADT

接口之間可以繼承

一個(gè)類可以實(shí)現(xiàn)多個(gè)接口

接口和實(shí)現(xiàn)

API的多個(gè)實(shí)現(xiàn)可以共存

多個(gè)類可以實(shí)現(xiàn)相同的API

他們?cè)谛阅芎托袨榉矫婵赡苡兴煌?/p>

在Java中,API由接口或類指定

接口只提供一個(gè)API

一個(gè)接口定義但不實(shí)現(xiàn)API

類提供了一個(gè)API和一個(gè)實(shí)現(xiàn)

一個(gè)類可以實(shí)現(xiàn)多個(gè)接口

一個(gè)接口可以有多種實(shí)現(xiàn)

Java接口和類

接口與類

接口:確定ADT規(guī)約

類:實(shí)現(xiàn)ADT

類確實(shí)定義了類型

類似接口方法的公共類方法

可從其他課程直接訪問(wèn)的公共字段

但更喜歡使用接口

除非你知道一個(gè)實(shí)現(xiàn)就足夠,否則使用變量和參數(shù)的接口類型。

支持更改實(shí)施;

防止依賴于實(shí)施細(xì)節(jié)

問(wèn)題:打破抽象邊界

客戶必須知道具體表示類的名稱。

因?yàn)镴ava中的接口不能包含構(gòu)造函數(shù),所以它們必須直接調(diào)用其中一個(gè)具體類的構(gòu)造函數(shù)。

構(gòu)造函數(shù)的規(guī)范不會(huì)出現(xiàn)在接口的任何位置,所以沒(méi)有任何靜態(tài)的保證,即使不同的實(shí)現(xiàn)甚至?xí)峁┫嗤臉?gòu)造函數(shù)。

接口的優(yōu)點(diǎn)

接口指定了客戶端的契約,僅此而已。

接口是客戶程序員需要閱讀才能理解ADT的全部?jī)?nèi)容。

客戶端不能在ADT的表示上創(chuàng)建無(wú)意的依賴關(guān)系,因?yàn)閷?shí)例變量根本無(wú)法放入接口。

實(shí)現(xiàn)完全保持完全分離,完全不同。 抽象數(shù)據(jù)類型的多個(gè)不同表示可以共存于同一個(gè)程序中,作為實(shí)現(xiàn)接口的不同類。

當(dāng)一個(gè)抽象數(shù)據(jù)類型被表示為一個(gè)多帶帶的類時(shí),如果沒(méi)有接口,就很難擁有多個(gè)表示。

為什么有多個(gè)實(shí)現(xiàn)

不同的表現(xiàn)

選擇最適合您使用的實(shí)現(xiàn)

不同的行為

選擇你想要的實(shí)現(xiàn)

行為必須符合接口規(guī)范(“契約”)

性能和行為往往不盡相同

提供功能

性能權(quán)衡

示例:HashSet,TreeSet

接口總結(jié)

編譯器和人員的文檔

允許性能權(quán)衡

可選的方法

有意識(shí)欠定規(guī)格的方法

一個(gè)類的多個(gè)視圖

越來(lái)越不值得信賴的實(shí)現(xiàn)

減少錯(cuò)誤保證安全

ADT由它的操作定義,而接口就是這樣做的。

當(dāng)客戶端使用接口類型時(shí),靜態(tài)檢查確保它們只使用接口定義的方法。

如果實(shí)現(xiàn)類暴露其他方法 - 或更糟糕的是,具有可見(jiàn)的表示 - 客戶端不會(huì)意外地看到或依賴它們。

當(dāng)我們有一個(gè)數(shù)據(jù)類型的多個(gè)實(shí)現(xiàn)時(shí),接口提供方法簽名的靜態(tài)檢查。

容易明白

客戶和維護(hù)人員確切知道在哪里查找ADT的規(guī)范。

由于接口不包含實(shí)例字段或?qū)嵗椒ǖ膶?shí)現(xiàn),因此更容易將實(shí)現(xiàn)的細(xì)節(jié)保留在規(guī)范之外。

準(zhǔn)備好改變

我們可以通過(guò)添加實(shí)現(xiàn)接口的類輕松地添加新類型的實(shí)現(xiàn)。

如果我們避免使用靜態(tài)工廠方法的構(gòu)造函數(shù),客戶端將只能看到該接口。

這意味著我們可以切換客戶端正在使用的實(shí)現(xiàn)類,而無(wú)需更改其代碼。

封裝和信息隱藏

信息隱藏

將精心設(shè)計(jì)的模塊與不好的模塊區(qū)分開(kāi)來(lái)的唯一最重要的因素是其隱藏內(nèi)部數(shù)據(jù)和其他模塊的其他實(shí)施細(xì)節(jié)的程度。
設(shè)計(jì)良好的代碼隱藏了所有的實(shí)現(xiàn)細(xì)節(jié)

將API與實(shí)施完全分開(kāi)

模塊只通過(guò)API進(jìn)行通信

對(duì)彼此的內(nèi)在運(yùn)作無(wú)知

被稱為信息隱藏或封裝,是軟件設(shè)計(jì)的基本原則。

信息隱藏的好處

將構(gòu)成系統(tǒng)的類分開(kāi)

允許它們獨(dú)立開(kāi)發(fā),測(cè)試,優(yōu)化,使用,理解和修改

加速系統(tǒng)開(kāi)發(fā)

類可以并行開(kāi)發(fā)

減輕了維護(hù)的負(fù)擔(dān)

可以更快速地理解類并調(diào)試,而不必害怕?lián)p害其他模塊

啟用有效的性能調(diào)整

“熱”類可以多帶帶優(yōu)化

增加軟件重用

松散耦合的類通常在其他情況下證明是有用的

通過(guò)接口隱藏信息

使用接口類型聲明變量
客戶端只能使用接口方法
客戶端代碼無(wú)法訪問(wèn)的字段
但我們到目前為止

客戶端可以直接訪問(wèn)非接口成員

實(shí)質(zhì)上,它是自愿的信息隱藏

成員的可見(jiàn)性修飾符

private - 只能從聲明類訪問(wèn)
protected - 可以從聲明類的子類(以及包內(nèi))
public - 從任何地方訪問(wèn)

信息隱藏的最佳實(shí)踐

仔細(xì)設(shè)計(jì)你的API
只提供客戶需要的功能,其他所有成員應(yīng)該是私人的
您可以隨時(shí)在不破壞客戶的情況下讓私人成員公開(kāi)

但反之亦然!

繼承和重寫

(1)重寫

可重寫的方法和嚴(yán)格的繼承
可重寫方法:允許重新實(shí)現(xiàn)的方法。

在Java方法中默認(rèn)是可重寫的,即沒(méi)有特殊的關(guān)鍵字。

嚴(yán)格的繼承

子類只能向超類添加新的方法,它不能覆蓋它們

如果某個(gè)方法不能在Java程序中被覆蓋,則必須以關(guān)鍵字final為前綴。

final

final字段:防止初始化后重新分配給字段
final方法:防止重寫該方法
final類:阻止繼承類

重寫

方法重寫是一種語(yǔ)言功能,它允許子類或子類提供已由其超類或父類之一提供的方法的特定實(shí)現(xiàn)。

相同的名稱,相同的參數(shù)或簽名,以及相同的返回類型。

執(zhí)行的方法的版本將由用于調(diào)用它的對(duì)象決定。實(shí)際執(zhí)行時(shí)調(diào)用哪個(gè)方法,運(yùn)行時(shí)決定。

如果父類的對(duì)象用于調(diào)用該方法,則會(huì)執(zhí)行父類中的版本;

如果使用子類的對(duì)象來(lái)調(diào)用該方法,則會(huì)執(zhí)行子類中的版本。

當(dāng)子類包含一個(gè)覆蓋超類方法的方法時(shí),它也可以使用關(guān)鍵字super調(diào)用超類方法。
重寫的時(shí)候,不要改變?cè)椒ǖ谋疽?/p>

(2)抽象類

抽象方法和抽象類

抽象方法:

具有簽名但沒(méi)有實(shí)現(xiàn)的方法(也稱為抽象操作)

由關(guān)鍵字abstract定義

抽象類:

一個(gè)包含至少一個(gè)抽象方法的類被稱為抽象類

接口:只有抽象方法的抽象類

接口主要用于系統(tǒng)或子系統(tǒng)的規(guī)范。 該實(shí)現(xiàn)由子類或其他機(jī)制提供。

具體類?抽象類?接口

多態(tài)性,子類型和重載

(1)三種多態(tài)性

特殊多態(tài)(Ad hoc polymorphism):當(dāng)一個(gè)函數(shù)表示不同且可能不同種類的實(shí)現(xiàn)時(shí),取決于多帶帶指定類型和組合的有限范圍。 使用函數(shù)重載(function overloading)在許多語(yǔ)言中支持特設(shè)多態(tài)。
參數(shù)化多態(tài)(parametric polymorphism):當(dāng)代碼被寫入時(shí)沒(méi)有提及任何特定類型,因此可以透明地使用任何數(shù)量的新類型。 在面向?qū)ο蟮木幊躺鐓^(qū)中,這通常被稱為泛型或泛型編程。
子類型多態(tài)(也稱為子類型多態(tài)或包含多態(tài)):當(dāng)名稱表示由一些公共超類相關(guān)的許多不同類的實(shí)例。

(2)特殊多態(tài)和重載

當(dāng)函數(shù)適用于幾種不同的類型(可能不會(huì)顯示公共結(jié)構(gòu))并且可能以不相關(guān)的方式表現(xiàn)每種類型時(shí),可以獲得特殊多態(tài)。

(3)重載

重載的方法允許您在類中重復(fù)使用相同的方法名稱,但使用不同的參數(shù)(以及可選的不同的返回類型)。
重載方法通常意味著對(duì)于那些調(diào)用方法的人來(lái)說(shuō)會(huì)更好一些,因?yàn)榇a承擔(dān)了應(yīng)對(duì)不同參數(shù)類型的負(fù)擔(dān),而不是在調(diào)用方法之前強(qiáng)制調(diào)用方執(zhí)行轉(zhuǎn)換。

函數(shù)重載可以在不同的實(shí)現(xiàn)中創(chuàng)建同名的多個(gè)方法。

對(duì)重載函數(shù)的調(diào)用將運(yùn)行適合于調(diào)用上下文的該函數(shù)的特定實(shí)現(xiàn),允許一個(gè)函數(shù)調(diào)用根據(jù)上下文執(zhí)行不同的任務(wù)。

重載是一種靜態(tài)多態(tài)

函數(shù)調(diào)用使用“最佳匹配技術(shù)”解決,即根據(jù)參數(shù)列表解析函數(shù)。

函數(shù)調(diào)用中的靜態(tài)類型檢查

在編譯時(shí)確定使用這些方法中的哪一個(gè)。(靜態(tài)類型檢查)

與之相反,重寫方法則是在運(yùn)行時(shí)進(jìn)行動(dòng)態(tài)檢查!

重載規(guī)則

函數(shù)重載中的規(guī)則:重載函數(shù)必須因參數(shù)或數(shù)據(jù)類型而有所不同

必須改變參數(shù)列表。

可以改變返回類型。

可以改變?cè)L問(wèn)修飾符。

可以聲明新的或更廣泛的檢查異常。

一個(gè)方法可以在同一個(gè)類或子類中重載。

重寫與重載

不要混淆覆蓋派生類中的方法和重載方法名稱

當(dāng)方法被覆蓋時(shí),派生類中給出的新方法定義與基類中的參數(shù)數(shù)量和類型完全相同

當(dāng)派生類中的方法與基類中的方法有不同的簽名時(shí),即重載

請(qǐng)注意,當(dāng)派生類重載原始方法時(shí),它仍然繼承基類中的原始方法

(3)參數(shù)多態(tài)性和泛型編程

當(dāng)一個(gè)函數(shù)在一系列類型上統(tǒng)一工作時(shí)獲得參數(shù)多態(tài)性; 這些類型通常具有一些共同的結(jié)構(gòu)。

它能夠以通用的方式定義函數(shù)和類型,以便它可以在運(yùn)行時(shí)傳遞參數(shù)的基礎(chǔ)上工作,即允許在沒(méi)有完全指定類型的情況下進(jìn)行靜態(tài)類型檢查。

這是Java中所謂的“泛型(Generic)”。

泛型編程是一種編程風(fēng)格,其中數(shù)據(jù)類型和函數(shù)是根據(jù)待指定的類型編寫的,隨后在需要時(shí)作為參數(shù)提供的特定類型實(shí)例化。

泛型編程圍繞從具體,高效的算法中抽象出來(lái)以獲得可與不同數(shù)據(jù)表示形式結(jié)合的泛型算法來(lái)生成各種各樣有用軟件的想法相關(guān)。

Java中的泛型

類型變量是一個(gè)不合格的標(biāo)識(shí)符。

它們由泛型類聲明,泛型接口聲明,泛型方法聲明和泛型構(gòu)造函數(shù)聲明引入。

如果一個(gè)類聲明一個(gè)或多個(gè)類型變量,則該類是通用的。

泛型類:其定義中包含了類型變量

這些類型的變量被稱為類的類型參數(shù)。

它定義了一個(gè)或多個(gè)作為參數(shù)的類型變量。

泛型類聲明定義了一組參數(shù)化類型,每個(gè)類型參數(shù)部分的每個(gè)可能的調(diào)用都有一個(gè)類型聲明。

所有這些參數(shù)化類型在運(yùn)行時(shí)共享相同的類。

如果聲明了類型變量,則interface是通用的。

這些類型變量被稱為接口的類型參數(shù)。

它定義了一個(gè)或多個(gè)作為參數(shù)的類型變量。

通用接口聲明定義了一組類型,每種類型參數(shù)部分的每個(gè)可能的調(diào)用都有一個(gè)類型。

所有參數(shù)化類型在運(yùn)行時(shí)共享相同的接口。

如果聲明類型變量,則方法是通用的。

這些類型的變量被稱為方法的形式類型參數(shù)。

形式類型參數(shù)列表的形式與類或接口的類型參數(shù)列表相同。

類型變量

使用菱形運(yùn)算符<>來(lái)幫助聲明類型變量。

一些Java泛型細(xì)節(jié)

可以有多個(gè)類型參數(shù)

例如Map ,Map

Wildcards通配符,只在使用泛型的時(shí)候出現(xiàn),不能在定義中出現(xiàn)

List <?> list = new ArrayList ();

List

List

通用類型信息被擦除(即僅編譯時(shí))

不能使用instanceof()來(lái)檢查通用類型運(yùn)行時(shí)泛型消失了!

無(wú)法創(chuàng)建通用數(shù)組

Pair [] foo = new Pair [42]; //不會(huì)編譯

(4)子類多態(tài)性

子類

一個(gè)類型是一組值。

Java List類型由接口定義。

如果我們考慮所有可能的List值,它們都不是List對(duì)象:我們不能創(chuàng)建接口的實(shí)例。

相反,這些值都是ArrayList對(duì)象或LinkedList對(duì)象,或者是實(shí)現(xiàn)List的另一個(gè)類的對(duì)象。
子類型只是超類型的一個(gè)子集

ArrayList和LinkedList是List的子類型。

繼承/子類型的好處:重用代碼,建模靈活性
在Java中:每個(gè)類只能直接繼承一個(gè)父類; 一個(gè)類可以實(shí)現(xiàn)多個(gè)接口。

“B是A的子類型”意思是“每個(gè)B都是A.”
在規(guī)格方面:“每個(gè)B都符合A的規(guī)格”。

如果B的規(guī)格至少和A的規(guī)格一樣強(qiáng),B只是A的一個(gè)子類型。 - 當(dāng)我們聲明一個(gè)實(shí)現(xiàn)接口的類時(shí),Java編譯器會(huì)自動(dòng)執(zhí)行這個(gè)需求的一部分:它確保A中的每個(gè)方法出現(xiàn)在B中,并帶有一個(gè)兼容的類型簽名。

B類不能實(shí)現(xiàn)接口A,而不實(shí)現(xiàn)A中聲明的所有方法。

靜態(tài)檢查子類型

但編譯器無(wú)法檢查我們是否以其他方式削弱了規(guī)范:

加強(qiáng)對(duì)某種方法的某些投入的先決條件

弱化后置條件

弱化接口抽象類型通告客戶端的保證。

如果你在Java中聲明了一個(gè)子類型(例如,實(shí)現(xiàn)一個(gè)接口),那么你必須確保子類型的規(guī)范至少和超類型一樣強(qiáng)。
子類型的規(guī)約不能弱化超類型的規(guī)約。

子類型多態(tài)

子類型多態(tài):不同類型的對(duì)象可以被客戶代碼統(tǒng)一處理子類型多態(tài):不同類型的對(duì)象可以統(tǒng)一的處理而無(wú)需區(qū)分
每個(gè)對(duì)象根據(jù)其類型行為(例如,如果添加新類型的帳戶,客戶端代碼不會(huì)更改)從而隔離了“變化”

Liskov替換原則(LSP):

如果S是T的子類型,那么類型T的對(duì)象可以用類型S的對(duì)象替換(即,類型T的對(duì)象可以用子類型S的任何對(duì)象代替)而不改變T的任何期望屬性。

instanceof

測(cè)試某個(gè)對(duì)象是否為給定類的運(yùn)算符
建議:如果可能,避免使用instanceof(),并且從不在超類中使用instanceof()來(lái)檢查針對(duì)子類的類型。

類型轉(zhuǎn)換

有時(shí)你想要一種不同于你已有的類型
如果你知道你有一個(gè)更具體的子類型,很有用
但是如果類型不兼容,它會(huì)得到一個(gè)ClassCastException

建議:

避免向下轉(zhuǎn)換類型

從不在超類內(nèi)向某個(gè)子類下降

動(dòng)態(tài)分派

動(dòng)態(tài)分派是選擇在運(yùn)行時(shí)調(diào)用多態(tài)操作的哪個(gè)實(shí)現(xiàn)的過(guò)程。

面向?qū)ο蟮南到y(tǒng)將一個(gè)問(wèn)題建模為一組交互對(duì)象,這些對(duì)象執(zhí)行按名稱引用的操作。

多態(tài)現(xiàn)象是這樣一種現(xiàn)象,即有些可互換的對(duì)象每個(gè)都暴露同一名稱的操作,但行為可能不同。

確定在運(yùn)行時(shí)要調(diào)用哪種方法,即對(duì)重寫或多態(tài)方法的調(diào)用可在運(yùn)行時(shí)解決

作為示例,F(xiàn)ile對(duì)象和Database對(duì)象都有一個(gè)StoreRecord方法,可用于將人員記錄寫入存儲(chǔ)。 他們的實(shí)現(xiàn)不同。

一個(gè)程序持有一個(gè)對(duì)象的引用,該對(duì)象可能是一個(gè)File對(duì)象或一個(gè)數(shù)據(jù)庫(kù)對(duì)象。 它可能是由運(yùn)行時(shí)間設(shè)置決定的,在這個(gè)階段,程序可能不知道或關(guān)心哪一個(gè)。
當(dāng)程序在對(duì)象上調(diào)用StoreRecord時(shí),需要確定哪些行為被執(zhí)行。
該程序?qū)toreRecord消息發(fā)送給未知類型的對(duì)象,并將其留給運(yùn)行時(shí)支持系統(tǒng)以將消息分派給正確的對(duì)象。 該對(duì)象實(shí)現(xiàn)它實(shí)現(xiàn)的任何行為。

動(dòng)態(tài)分派與靜態(tài)分派形成對(duì)比,其中在編譯時(shí)選擇多態(tài)操作的實(shí)現(xiàn)。

動(dòng)態(tài)分派的目的是為了支持在編譯時(shí)無(wú)法確定多態(tài)操作的適當(dāng)實(shí)現(xiàn)的情況,因?yàn)樗蕾囉诓僮鞯囊粋€(gè)或多個(gè)實(shí)際參數(shù)的運(yùn)行時(shí)類型。

靜態(tài)分派:編譯階段即可確定要執(zhí)行哪個(gè)具體操作。
重載的方法使用靜態(tài)分派,而重寫的方法在運(yùn)行時(shí)使用動(dòng)態(tài)分派。

動(dòng)態(tài)分派不同于動(dòng)態(tài)綁定(也稱為動(dòng)態(tài)綁定)。

選擇操作時(shí),綁定會(huì)將名稱與操作關(guān)聯(lián)。

在決定了名稱引用的操作后,分派會(huì)為操作選擇一個(gè)實(shí)現(xiàn)。

綁定:將調(diào)用的名字與實(shí)際的方法名字聯(lián)系起來(lái)(可能很多個(gè));
分派:具體執(zhí)行哪個(gè)方法(提前綁定→靜態(tài)分派)

通過(guò)動(dòng)態(tài)分派,該名稱可以在編譯時(shí)綁定到多態(tài)操作,但不會(huì)在運(yùn)行時(shí)間之前選擇實(shí)現(xiàn)。動(dòng)態(tài)分派:編譯階段可能綁定到多態(tài)操作,運(yùn)行階段決定具體執(zhí)行哪個(gè)(覆蓋和過(guò)載均是如此);

雖然動(dòng)態(tài)分派并不意味著動(dòng)態(tài)綁定,但動(dòng)態(tài)綁定確實(shí)意味著動(dòng)態(tài)分派,因?yàn)榻壎Q定了可用分派的集合。

提前/靜態(tài)綁定

每當(dāng)發(fā)生靜態(tài),私有和最終方法的綁定時(shí),類的類型由編譯器在編譯時(shí)確定,并且綁定在那里和那里發(fā)生。

推遲/動(dòng)態(tài)綁定

重寫父類和子類都有相同的方法,在這種情況下,對(duì)象的類型決定了要執(zhí)行哪種方法。 對(duì)象的類型在運(yùn)行時(shí)確定。

動(dòng)態(tài)方法分派

1.(編譯時(shí))確定要查找哪個(gè)類
2.(編譯時(shí))確定要執(zhí)行的方法簽名

查找所有可訪問(wèn)的適用方法

選擇最具體的匹配方法

3.(運(yùn)行時(shí))確定接收器的動(dòng)態(tài)類別
4.(運(yùn)行時(shí))從動(dòng)態(tài)類中,找到要調(diào)用的方法

在第2步中找到具有相同簽名的方法

否則在超類中搜索等。

10 Java中的一些重要的Object方法

equals() - 如果兩個(gè)對(duì)象“相等”,則為true
hashCode() - 用于哈希映射的哈希代碼
toString() - 可打印的字符串表示形式

toString() - 丑陋而無(wú)信息

你知道你的目標(biāo)是什么,所以你可以做得更好

總是覆蓋,除非你知道不會(huì)被調(diào)用

equals&hashCode - 身份語(yǔ)義

如果你想要價(jià)值語(yǔ)義,你必須重寫

否則不要

設(shè)計(jì)好的類

不可變類的優(yōu)點(diǎn)

簡(jiǎn)單
本質(zhì)上是線程安全的
可以自由分享
不需要防御式拷貝
優(yōu)秀的積木

如何編寫一個(gè)不可變的類

不要提供任何變值器
確保沒(méi)有方法可能被覆蓋
使所有的領(lǐng)域最終
使所有字段保密
確保任何可變組件的安全性(避免重復(fù)曝光)
實(shí)現(xiàn)toString(),hashCode(),clone(),equals()等。

何時(shí)讓類不可變
總是,除非有充分的理由不這樣做
總是讓小型“價(jià)值類”永恒不變!

何時(shí)讓類可變

類表示狀態(tài)改變的實(shí)體

真實(shí)世界 - 銀行賬戶,紅綠燈

抽象 - 迭代器,匹配器,集合

進(jìn)程類 - 線程,計(jì)時(shí)器

如果類必須是可變的,則最小化可變性

構(gòu)造函數(shù)應(yīng)該完全初始化實(shí)例

避免重新初始化方法

OOP的歷史

仿真和面向?qū)ο缶幊痰钠鹪?/p>

20世紀(jì)60年代:Simula 67是第一個(gè)由Kristin Nygaardand Ole-Johan Dahl在挪威計(jì)算中心開(kāi)發(fā)的面向?qū)ο笳Z(yǔ)言,用于支持離散事件模擬。 (類,對(duì)象,繼承等)
“面向?qū)ο缶幊蹋∣OP)”這個(gè)術(shù)語(yǔ)最早是由施樂(lè)PARC在他們的Smalltalk語(yǔ)言中使用的。
20世紀(jì)80年代:面向?qū)ο笠呀?jīng)變得非常突出,而其中的主要因素是C ++。
NiklausWirth用于Oberon和Modula-2的模塊化編程和數(shù)據(jù)抽象;
埃菲爾和Java

總結(jié)

面向?qū)ο蟮臉?biāo)準(zhǔn)
基本概念:對(duì)象,類,屬性,方法和接口
OOP的獨(dú)特功能

封裝和信息隱藏
繼承和重寫
多態(tài)性,子類型和重載
靜態(tài)和動(dòng)態(tài)調(diào)度

Java中一些重要的Object方法
編寫一個(gè)不可變的類
OOP的歷史

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/71327.html

相關(guān)文章

  • 3抽象數(shù)據(jù)類型ADT面向對(duì)象編程OOP3.5 ADTOOP中的等價(jià)性

    摘要:抽象函數(shù)引發(fā)的關(guān)系是等價(jià)關(guān)系。所以當(dāng)且僅當(dāng)通過(guò)調(diào)用抽象數(shù)據(jù)類型的任何操作不能區(qū)分它們時(shí),兩個(gè)對(duì)象是相等的。必須為每個(gè)抽象數(shù)據(jù)類型適當(dāng)?shù)囟x操作。一般來(lái)說(shuō),在面向?qū)ο缶幊讨惺褂檬且环N陋習(xí)。 大綱 什么是等價(jià)性?為什么要討論等價(jià)性?三種等價(jià)性的方式==與equals()不可變類型的等價(jià)性對(duì)象契約可變類型的等價(jià)性自動(dòng)包裝和等價(jià)性 什么是等價(jià)性?為什么要討論等價(jià)性? ADT上的相等操作 ADT...

    Fundebug 評(píng)論0 收藏0
  • 3抽象數(shù)據(jù)類型ADT面向對(duì)象編程OOP3.2設(shè)計(jì)規(guī)約

    摘要:程序失敗時(shí),很難確定錯(cuò)誤的位置。它保護(hù)客戶免受單位工作細(xì)節(jié)的影響。將前提條件放在中,并將后置條件放入和。涉及可變對(duì)象的契約現(xiàn)在取決于每個(gè)引用可變對(duì)象的每個(gè)人的良好行為。設(shè)計(jì)規(guī)約按規(guī)約分類比較規(guī)約它是如何確定性的。 大綱 1.編程語(yǔ)言中的功能/方法2.規(guī)約:便于交流的編程,為什么需要規(guī)約 行為等同規(guī)約結(jié)構(gòu):前提條件和后條件測(cè)試和驗(yàn)證規(guī)約3.設(shè)計(jì)規(guī)約分類規(guī)約圖表規(guī)約質(zhì)量規(guī)約4.總結(jié) 編程...

    mozillazg 評(píng)論0 收藏0
  • 3抽象數(shù)據(jù)類型ADT面向對(duì)象編程OOP3.1數(shù)據(jù)類型類型檢查

    摘要:所有變量的類型在編譯時(shí)已知在程序運(yùn)行之前,因此編譯器也可以推導(dǎo)出所有表達(dá)式的類型。像變量的類型一樣,這些聲明是重要的文檔,對(duì)代碼讀者很有用,并由編譯器進(jìn)行靜態(tài)檢查。對(duì)象類型的值對(duì)象類型的值是由其類型標(biāo)記的圓。 大綱 1.編程語(yǔ)言中的數(shù)據(jù)類型2.靜態(tài)與動(dòng)態(tài)數(shù)據(jù)類型3.類型檢查4.易變性和不變性5.快照?qǐng)D6.復(fù)雜的數(shù)據(jù)類型:數(shù)組和集合7.有用的不可變類型8.空引用9.總結(jié) 編程語(yǔ)言中的數(shù)據(jù)...

    zhangqh 評(píng)論0 收藏0
  • 軟件構(gòu)造lab2

    摘要:本次實(shí)驗(yàn)訓(xùn)練抽象數(shù)據(jù)類型的設(shè)計(jì)規(guī)約測(cè)試,并使用面向?qū)ο缶幊碳夹g(shù)實(shí)現(xiàn)。改成泛型將函數(shù)聲明和調(diào)用等修改一下即可調(diào)用之前我們實(shí)現(xiàn)的一個(gè)圖結(jié)構(gòu)實(shí)現(xiàn)方法如下讀取文件輸入,識(shí)別序列,構(gòu)建圖結(jié)構(gòu)。 本次實(shí)驗(yàn)訓(xùn)練抽象數(shù)據(jù)類型(ADT)的設(shè)計(jì)、規(guī)約、測(cè)試,并使用面向?qū)ο缶幊蹋∣OP)技術(shù)實(shí)現(xiàn) ADT。 3.1 Poetic Walks建立對(duì)ADT的基本印象,比如如何設(shè)計(jì)一個(gè)能夠泛型化的ADT。加深對(duì)AF...

    孫吉亮 評(píng)論0 收藏0
  • 樂(lè)字節(jié)Java編程語(yǔ)言發(fā)展、面向對(duì)象

    摘要:二面向?qū)ο蟾攀雒嫦蜻^(guò)程的設(shè)計(jì)思想和面向?qū)ο蟮脑O(shè)計(jì)思想我要吃魚香肉絲蓋飯面向過(guò)程我買菜我洗菜我切菜我放水我點(diǎn)火我做飯我炒菜。。。。 大家好,上次我們講過(guò)了樂(lè)字節(jié)Java編程之方法、調(diào)用、重載、遞歸,接下來(lái)我們將會(huì)進(jìn)入到Java封裝的內(nèi)容。Java編程語(yǔ)言發(fā)展,面向?qū)ο蠛皖悺?一、編程語(yǔ)言的發(fā)展 機(jī)器語(yǔ)言——直接由計(jì)算機(jī)的指令組成,指令、數(shù)據(jù)、地址都以0和1組成:可以被計(jì)算機(jī)直接識(shí)別并執(zhí)行...

    lufficc 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<