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