(1)封裝:通常認(rèn)為封裝是把數(shù)據(jù)和操作數(shù)據(jù)的方法綁定起來,對(duì)數(shù)據(jù)的訪問只能通過已定義的接口。面向?qū)ο蟮谋举|(zhì)就是將現(xiàn)實(shí)世界描繪成一系列完全自治、封閉的對(duì)象。我們?cè)陬愔芯帉懙姆椒ň褪菍?duì)實(shí)現(xiàn)細(xì)節(jié)的一種封裝;我們編寫一個(gè)類就是對(duì)數(shù)據(jù)和數(shù)據(jù)操作的封裝。可以說,封裝就是隱藏一切可隱藏的東西,只向外界提供最簡(jiǎn)單的編程接口。
(2)繼承:繼承是從已有類得到繼承信息創(chuàng)建新類的過程。提供繼承信息的類被稱為父類(超類、基類);得到繼承信息的類被稱為子類(派生類)。繼承讓變化中的軟件系統(tǒng)有了一定的延續(xù)性,同時(shí)繼承也是封裝程序中可變因素的重要手段。
(3)多態(tài):多態(tài)性是指允許不同子類型的對(duì)象對(duì)同一消息作出不同的響應(yīng)。簡(jiǎn)單的說就是用同樣的對(duì)象引用調(diào)用同樣的方法但是做了不同的事情。多態(tài)性分為編譯時(shí)的多態(tài)性和運(yùn)行時(shí)的多態(tài)性。如果將對(duì)象的方法視為對(duì)象向外界提供的服務(wù),那么運(yùn)行時(shí)的多態(tài)性可以解釋為:當(dāng) A系統(tǒng)訪問B系統(tǒng)提供的服務(wù)時(shí),B 系統(tǒng)有多種提供服務(wù)的方式,但一切對(duì) A 系統(tǒng)來說都是透明的。方法重載(overload)實(shí)現(xiàn)的是編譯時(shí)的多態(tài)性(也稱為前綁定),而方法重寫(override)實(shí)現(xiàn)的是運(yùn)行時(shí)的多態(tài)性(也稱為后綁定)。運(yùn)行時(shí)的多態(tài)是面向?qū)ο笞罹璧臇|西,要實(shí)現(xiàn)多態(tài)需要做兩件事:
第一:方法重寫(子類繼承父類并重寫父類中已有的或抽象的方法);
第二:對(duì)象造型(用父類型引用指向子類型對(duì)象,這樣同樣的引用調(diào)用同樣的方法就會(huì)根據(jù)子類對(duì)象的不同而表現(xiàn)出不同的行為)。
(4)抽象:抽象是將一類對(duì)象的共同特征總結(jié)出來構(gòu)造類的過程,包括數(shù)據(jù)抽象和行為抽象兩方面。抽象只關(guān)注對(duì)象有哪些屬性和行為,并不關(guān)注這些行為的細(xì)節(jié)是什么。
修飾符 |
當(dāng)前類 |
同包 |
子類 |
其他包 |
public |
√ |
√ |
√ |
√ |
protected |
√ |
√ |
√ |
× |
默認(rèn)(缺?。?/span> |
√ |
√ |
× |
× |
private |
√ |
× |
× |
× |
在實(shí)際編程過程中,我們常常要遇到這種情況:有一個(gè)對(duì)象 A,在某一時(shí)刻 A 中已經(jīng)包含了一些有效值,此時(shí)可能會(huì)需要一個(gè)和 A 完全相同新對(duì)象 B,并且此后對(duì) B 任何改動(dòng)都不會(huì)影響到 A 中的值,也就是說,A 與 B 是兩個(gè)獨(dú)立的對(duì)象,但 B 的初始值是由 A 對(duì)象確定的。在 Java 語言中,用簡(jiǎn)單的賦值語句是不能滿足這種需求的。要滿足這種需求雖然有很多途徑,但clone()方法是其中最簡(jiǎn)單,也是最高效的手段。
● 說到對(duì)象的克隆,涉及到深克隆和淺克?。?/span>
淺克隆:創(chuàng)建一個(gè)新對(duì)象,新對(duì)象的屬性和原來對(duì)象完全相同,對(duì)于非基本類型屬性,仍指向原有屬性所指向的對(duì)象的內(nèi)存地址。
深克隆:創(chuàng)建一個(gè)新對(duì)象,屬性中引用的其他對(duì)象也會(huì)被克隆,不再指向原有對(duì)象地址。
new 操作符的本意是分配內(nèi)存。程序執(zhí)行到 new 操作符時(shí),首先去看 new 操作符后面的類型,因?yàn)橹懒祟愋?,才能知道要分配多大的?nèi)存空間。分配完內(nèi)存之后,再調(diào)用構(gòu)造函數(shù),填充對(duì)象的各個(gè)域,這一步叫做對(duì)象的初始化,構(gòu)造方法返回后,一個(gè)對(duì)象創(chuàng)建完畢,可以把他的引用(地址)發(fā)布到外部,在外部就可以使用這個(gè)引用操縱這個(gè)對(duì)象。
clone 在第一步是和 new 相似的,都是分配內(nèi)存,調(diào)用 clone 方法時(shí),分配的內(nèi)存和原對(duì)象(即調(diào)用 clone 方法的對(duì)象)相同,然后再使用原對(duì)象中對(duì)應(yīng)的各個(gè)域,填充新對(duì)象的域,填充完成之后,clone方法返回,一個(gè)新的相同的對(duì)象被創(chuàng)建,同樣可以把這個(gè)新對(duì)象的引用發(fā)布到外部。
Java中的多態(tài)靠的是父類或接口定義的引用變量可以指向子類或具體實(shí)現(xiàn)類的實(shí)例對(duì)象,而程序調(diào)用的方法在運(yùn)行期才動(dòng)態(tài)綁定,就是引用變量所指向的具體實(shí)例對(duì)象的方法,也就是內(nèi)存里正在運(yùn)行的那個(gè)對(duì)象的方法,而不是引用變量的類型中定義的方法。
多態(tài)就是指程序中定義的引用變量所指向的具體類型和通過該引用變量發(fā)出的方法調(diào)用在編程時(shí)并不確定,而是在程序運(yùn)行期間才確定,即一個(gè)引用變量到底會(huì)指向哪個(gè)類的實(shí)例對(duì)象,該引用變量發(fā)出的方法調(diào)用到底是哪個(gè)類中實(shí)現(xiàn)的方法,必須在程序運(yùn)行期間才能決定。因?yàn)樵诔绦蜻\(yùn)行時(shí)才確定具體的類,這樣,不用修改源代碼,就可以讓引用變量綁定到各種不同的對(duì)象上,從而導(dǎo)致該引用調(diào)用的具體方法隨之改變,即不修改程序代碼就可以改變程序運(yùn)行時(shí)所綁定的具體代碼,讓程序可以選擇多個(gè)運(yùn)行狀態(tài),這就是多態(tài)性。
所謂對(duì)象就是由一組數(shù)據(jù)結(jié)構(gòu)和處理它們的方法組成的,重點(diǎn)“數(shù)據(jù)”包括對(duì)象的特性、狀態(tài)等的靜態(tài)信息;“方法” 也就是行為,包括該對(duì)象的對(duì)數(shù)據(jù)的操作、功能等能動(dòng)信息。把相同行為的對(duì)象歸納為類,類是一個(gè)抽象的概念,對(duì)象是類的具體。簡(jiǎn)單點(diǎn)說:對(duì)象就是類的實(shí)例。例如:小品演員就是一個(gè)類,趙本山就是一個(gè)對(duì)象。
面向?qū)ο蟮哪康模航鉀Q軟件系統(tǒng)的可擴(kuò)展性,可維護(hù)性和可重用性。
● 面向?qū)ο蟮娜筇匦裕悍庋b、多態(tài)和繼承:
(1)封裝(對(duì)應(yīng)可擴(kuò)展性):隱藏對(duì)象的屬性和實(shí)現(xiàn)細(xì)節(jié),僅對(duì)外公開接口,控制在程序中屬性的讀和修改的訪問級(jí)別。封裝是通過訪問控制符(public protected private)來實(shí)現(xiàn)。一個(gè)類就可看成一個(gè)封裝。
(2)繼承(重用性和擴(kuò)展性):子類繼承父類,可以繼承父類的方法和屬性??梢詫?duì)父類方向進(jìn)行覆蓋(實(shí)現(xiàn)了多態(tài))。但是繼承破壞了封裝,因?yàn)樗菍?duì)子類開放的,修改父類會(huì)導(dǎo)致所有子類的改變,因此繼承一定程度上又破壞了系統(tǒng)的可擴(kuò)展性,只有明確的IS-A關(guān)系才能使用。繼承要慎用,盡量優(yōu)先使用組合。
(3)多態(tài)(可維護(hù)性和可擴(kuò)展性):接口的不同實(shí)現(xiàn)方式即為多態(tài)。接口是對(duì)行為的抽象,剛才在封裝提到,找到變化部分并封裝起來,但是封裝起來后,怎么適應(yīng)接下來的變化?這正是接口的作用,接口的主要目的是為不相關(guān)的類提供通用的處理服務(wù),我們可以想象一下。比如鳥會(huì)飛,但是超人也會(huì)飛,通過飛這個(gè)接口,我們可以讓鳥和超人,都實(shí)現(xiàn)這個(gè)接口。
面向?qū)ο缶幊蹋∣OP)其實(shí)就是一種設(shè)計(jì)思想,在程序設(shè)計(jì)過程中把每一部分都盡量當(dāng)成一個(gè)對(duì)象來考慮,以實(shí)現(xiàn)軟件系統(tǒng)的可擴(kuò)展性,可維護(hù)性和可重用性。