面向?qū)ο蟮娜筇卣鳎?strong>封裝、繼承、多態(tài)
一、封裝
首先,屬性能夠描述事物的特征,方法能夠描述事物的動(dòng)作。封裝就是把同一類事物的共性(包括屬性和方法)歸到同一類中,方便使用。
- 封裝:
封裝也稱信息隱藏,是指利用抽象數(shù)據(jù)類型把數(shù)據(jù)和基于數(shù)據(jù)的操作封裝起來(lái),使其成為一個(gè)不可分割的整體,數(shù)據(jù)隱藏在抽象數(shù)據(jù)內(nèi)部,盡可能的隱藏?cái)?shù)據(jù)細(xì)節(jié),只保留一些接口使其與外界發(fā)生聯(lián)系。也就是說(shuō)用戶無(wú)需知道內(nèi)部的數(shù)據(jù)和方法的具體實(shí)現(xiàn)細(xì)節(jié),只需根據(jù)留在外部的接口進(jìn)行操作就行。 - 封裝的好處:
- 實(shí)現(xiàn)了專業(yè)的分工
- 良好的封裝能夠減少耦合
- 類內(nèi)部的結(jié)構(gòu)能夠自由修改
- 可以對(duì)成員進(jìn)行更精確的控制
- 隱藏信息,實(shí)現(xiàn)細(xì)節(jié)
- 封裝的步驟:
- 修改屬性的可見(jiàn)性來(lái)限制對(duì)屬性的訪問(wèn)
- 為每個(gè)屬性創(chuàng)建一對(duì)賦值和取值方法,用于對(duì)這些屬性的訪問(wèn)
- 在賦值和取值方法中,加入對(duì)屬性的存取限制
二、繼承
- Java繼承
- Java繼承是面向?qū)ο蟮淖铒@著的一個(gè)特征。繼承是從已有的類中派生出新的類,新的類能吸收已有類的數(shù)據(jù)屬性和行為,并能擴(kuò)展新的能力。
- JAVA不支持多繼承,單繼承使JAVA的繼承關(guān)系很簡(jiǎn)單,一個(gè)類只能有一個(gè)父類,易于管理程序,父類是子類的一般化,子類是父類的特化(具體化)。
- Java繼承的特征
- 繼承關(guān)系是傳遞的。若類C繼承類B,類B繼承類A(多繼承),則類C既有從類B那里繼承下來(lái)的屬性與方法,也有從類A那里繼承下來(lái)的屬性與方法。
- 繼承提供了軟件復(fù)用功能。若類B繼承類A,那么建立類B時(shí)只需要再描述與基類(類A)不同的少量特征(數(shù)據(jù)成員和成員方法)即可。這種做法能減小代碼和數(shù)據(jù)的冗余度,大大增加程序的重用性。
- 繼承通過(guò)增強(qiáng)一致性來(lái)減少模塊間的接口和界面,大大增加了程序的易維護(hù)性。
- 結(jié)果:
繼承后子類自動(dòng)擁有了父類的屬性和方法,但特別注意的是,父類的私有屬性和構(gòu)造方法并不能被繼承。
三、多態(tài)
- 多態(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)系。 - 多態(tài)存在的三個(gè)必要條件
- 要有繼承;
- 要有重寫;
- 父類引用指向子類對(duì)象。
- 好處:
- 可替換性(substitutability)。多態(tài)對(duì)已存在代碼具有可替換性。例如,多態(tài)對(duì)圓Circle類工作,對(duì)其他任何圓形幾何體,如圓環(huán),也同樣工作。
- 可擴(kuò)充性(extensibility)。多態(tài)對(duì)代碼具有可擴(kuò)充性。增加新的子類不影響已存在類的多態(tài)性、繼承性,以及其他特性的運(yùn)行和操作。實(shí)際上新加子類更容易獲得多態(tài)功能。
- 接口性(interface-ability)。多態(tài)是超類通過(guò)方法簽名,向子類提供了一個(gè)共同接口,由子類來(lái)完善或者覆蓋它而實(shí)現(xiàn)的。
- 靈活性(flexibility)。它在應(yīng)用中體現(xiàn)了靈活多樣的操作,提高了使用效率。
- 簡(jiǎn)化性(simplicity)。多態(tài)簡(jiǎn)化對(duì)應(yīng)用軟件的代碼編寫和修改過(guò)程,尤其在處理大量對(duì)象的運(yùn)算和操作時(shí),這個(gè)特點(diǎn)尤為突出和重要。
四、例子
比如你是一個(gè)酒神,對(duì)酒情有獨(dú)鐘。某日回家發(fā)現(xiàn)桌上有幾個(gè)杯子里面都裝了白酒,從外面看我們是不可能知道這是些什么酒,只有喝了之后才能夠猜出來(lái)是何種酒。你一喝,這是劍南春、再喝這是五糧液、再喝這是酒鬼酒….在這里我們可以描述成如下:
酒 a = 劍南春
酒 b = 五糧液
酒 c = 酒鬼酒
…
這里所表現(xiàn)的的就是多態(tài)。
public class Wine {
public void fun1(){
System.out.println("Wine 的Fun.....");
fun2();
}
public void fun2(){
System.out.println("Wine 的Fun2...");
}
}
public class JNC extends Wine{
/**
* 子類重載父類方法,父類中不存在該方法,向上轉(zhuǎn)型后,父類是不能引用該方法的
*/
public void fun1(String a){
System.out.println("JNC 的 Fun1...");
fun2();
}
/**
* 子類重寫父類方,指向子類的父類引用調(diào)用fun2時(shí),必定是調(diào)用該方法
*/
public void fun2(){
System.out.println("JNC 的Fun2...");
}
}
public class Test {
public static void main(String[] args) {
Wine a = new JNC();
a.fun1();
}
}
-------------------------------------------------
Output:Wine 的Fun.....JNC 的Fun2...
五、總結(jié):
指向子類的父類引用由于向上轉(zhuǎn)型了,它只能訪問(wèn)父類中擁有的方法和屬性,而對(duì)于子類中存在而父類中不存在的方法,該引用是不能使用的,盡管是重載該方法。若子類重寫了父類中的某些方法,在調(diào)用該些方法的時(shí)候,必定是使用子類中定義的這些方法(動(dòng)態(tài)連接、動(dòng)態(tài)調(diào)用)。