1: Introduction to Objects(對(duì)象簡(jiǎn)介)
抽象的過(guò)程
問(wèn)題空間的元素同它在解決空間的表述稱為“對(duì)象”。(此外還需要一些在問(wèn)題空間并無(wú)對(duì)照的對(duì)象。)
面向?qū)ο蟮木幊蹋∣bject-oriented programming,縮寫是OOP)方法:
1. 萬(wàn)物皆對(duì)象。
2. 程序就是一組相互之間傳遞消息,告訴對(duì)方干些什么的對(duì)象。
3. 每個(gè)對(duì)象都利用別的對(duì)象來(lái)組建它自己的記憶。
4. 對(duì)象都有類型。
5. 所有屬于同一類型的對(duì)象都能接受相同的消息。
對(duì)象有狀態(tài)、行為和標(biāo)識(shí)。
對(duì)象有接口
類是一組具有相同特征(數(shù)據(jù)元素)和行為(功能)的對(duì)象,所以實(shí)際上類是一種數(shù)據(jù)類型。
區(qū)別:類是程序員為解決特定問(wèn)題而定做的,而數(shù)據(jù)類型是為了表示機(jī)器的存儲(chǔ)單元而設(shè)計(jì)的,它是現(xiàn)成的,是程序員無(wú)可奈何時(shí)的選擇。
對(duì)象會(huì)提供服務(wù)
優(yōu)點(diǎn):能提高對(duì)象的內(nèi)聚性(cohesion)。內(nèi)聚性高是高質(zhì)量的軟件設(shè)計(jì)的一個(gè)基本要求:就是說(shuō)軟件的各種組件(比如對(duì)象,也可以是方法或類庫(kù))應(yīng)該能很好的“組裝在一起”。
隱藏實(shí)現(xiàn)
public表示后面跟著的東西誰(shuí)都能用。
而private關(guān)鍵詞則表示,除非是類的創(chuàng)建者用這個(gè)類的方法進(jìn)行訪問(wèn),否則沒(méi)人能訪問(wèn)到這個(gè)元素。private是豎在你與客戶程序員之間的一堵墻。那些要訪問(wèn)private成員的人,會(huì)在編譯的時(shí)候得到一個(gè)錯(cuò)誤。
protected關(guān)鍵詞很像private,它們的區(qū)別在于,繼承類能夠訪問(wèn)protected成員,但是不能訪問(wèn)private成員。
Java還有個(gè)“缺省”的訪問(wèn)權(quán)限,如果你沒(méi)用上面三個(gè)的話,那就是指它了。通常把它成為package訪問(wèn)權(quán)限。因?yàn)橥瑢龠@個(gè)package的類可以訪問(wèn)這個(gè)package中其它類的“缺省權(quán)限”的成員,但是出了這個(gè)package,它們就都是private的了。
復(fù)用實(shí)現(xiàn)
由于是用已有的類來(lái)合成新的類,因此這一概念被成為合成(composition,如果這個(gè)對(duì)象是動(dòng)態(tài)的,通常把它成為聚合aggregation)。通常將合成稱為“有(has-a)”關(guān)系,就像“轎車有引擎”。
合成具有極大的靈活性。
繼承:復(fù)用接口
你有兩種辦法來(lái)區(qū)分新的派生出來(lái)的類和那個(gè)原來(lái)的基類。
1. 直接往派生類里加新的方法。
2. 也是更重要的區(qū)分方法是在新的類中修改基類方法的行為。這被稱為覆寫(override)那個(gè)方法。
“是”與“像”的關(guān)系
1. 結(jié)果是能用派生類的對(duì)象直接替換基類的對(duì)象。可以把這種情況想成完全替換(pure substitution),通常被稱為替換原則(substitution principle)。從某種意義上講,這是使用繼承的理想方法。通常我們把基類同派生類的這種關(guān)系稱作是(is-a)關(guān)系。
2. 基類還是可以被新的類所替代,但是這種替換是不完全的,因?yàn)榈姆椒o(wú)法通過(guò)基類的接口訪問(wèn)。這可以被稱為“像(is-like-a)”關(guān)系。
可憑借多態(tài)性相互替換的對(duì)象
非OOP的編譯器的做法被稱為前綁定(early binding)。在OOP中,不到運(yùn)行的時(shí)候,程序沒(méi)法確定代碼的地址,所以向泛型對(duì)象發(fā)送一個(gè)消息的時(shí)候,就要用到一些特別的手段。為了解決這個(gè)問(wèn)題,OOP語(yǔ)言是用了后綁定(late binding)的概念。
將派生類當(dāng)作它的基類來(lái)用的過(guò)程稱為上傳(upcast)。
abstract基類和interface
abstract方法只能存在于abstract類里。如果有個(gè)類繼承了abstract類,那么它要么實(shí)現(xiàn)這個(gè)方法,要么也是一個(gè)abstract類。abstract方法能讓你將方法放到接口而不必為它寫一些無(wú)意義的代碼。
interface關(guān)鍵詞更是對(duì)abstract類的概念的深化,它不允許你實(shí)現(xiàn)任何方法。interface是個(gè)很趁手也很常用的工具,因?yàn)樗軓氐椎貙⒔涌谂c實(shí)現(xiàn)分離開(kāi)來(lái)。此外如果你愿意,還可以繼承多個(gè)接口,因?yàn)橐^承多個(gè)常規(guī)或是抽象類是不允許的。
對(duì)象的創(chuàng)建,使用和生命周期
1. 在寫代碼的時(shí)候決定將對(duì)象放到棧里(有時(shí)會(huì)被稱為automatic或scoped的變量)或是靜態(tài)的存儲(chǔ)區(qū)域。(C++,速度快)
2. 在一個(gè)被稱為堆的內(nèi)存池里動(dòng)態(tài)地創(chuàng)建對(duì)象。(Java,靈活性高)
(在棧中分配存儲(chǔ)空間通常只需一個(gè)匯編指令,把棧指針向下移就行了,想把指針指回來(lái)也只要一條指令。而堆的存儲(chǔ)分配則取決于存儲(chǔ)機(jī)制的設(shè)計(jì)。)
Collection和迭代器
List類(以持有線性序列)
Map類(也稱為關(guān)聯(lián)性數(shù)組associative arrays,將一個(gè)對(duì)象同另一個(gè)對(duì)象關(guān)聯(lián)起來(lái))
Set類(不持有兩個(gè)相同的對(duì)象)
單根繼承體系
Java(實(shí)際上除了C++所有其它OOP語(yǔ)言)的回答是,是的,而這個(gè)最終的基類就叫Object.
下傳與模板/泛型
沿著繼承圖向下傳給一個(gè)更為具體的類型,這種方式稱為下傳(downcast)。
上傳很安全,下傳十有八九是不安全的。
參數(shù)化類型(parameterized type)是一種能夠根據(jù)需要由編譯器自動(dòng)指派類型的類。(C++:template/Java:generics)
確保正確地清除
Java設(shè)計(jì)了一個(gè)垃圾回收器來(lái)處理釋放內(nèi)存的問(wèn)題(僅此而已,不包括清除對(duì)象的其它方面)。
垃圾回收器的效率與靈活性
C++:編程復(fù)雜性較高
Java:效率和適用性較差
異常處理:與錯(cuò)誤打交道
盡管在面向?qū)ο蟮恼Z(yǔ)言中異常通常以對(duì)象的形式出現(xiàn),但異常處理并不是一種面向?qū)ο蟮奶匦浴.惓L幚碓诿嫦驅(qū)ο蟮恼Z(yǔ)言問(wèn)世之前就已經(jīng)有了。
并發(fā)
Java能鎖定任何對(duì)象的內(nèi)存(畢竟這也是一種共享資源),這樣同一時(shí)刻就只有一個(gè)線程能夠訪問(wèn)這些內(nèi)存。這是由synchronized關(guān)鍵詞來(lái)做的。其它資源就得靠程序員自己來(lái)鎖定了。通常可以創(chuàng)建一個(gè)表示這項(xiàng)資源的對(duì)象,然后讓線程在訪問(wèn)資源之前先檢查一下。
Persistence
輕量級(jí)的presistence既可以通過(guò)對(duì)象的序列化(object serialization),也可以通過(guò)數(shù)據(jù)對(duì)象(Java Data Object,簡(jiǎn)稱JDO)來(lái)實(shí)現(xiàn)。
Java和Internat
Web是什么?
客戶/服務(wù)器系統(tǒng)
把Web當(dāng)作巨型的服務(wù)器
客戶端編程
插件
腳本語(yǔ)言
Java
.NET和C#
安全性
Internet和Intranet
服務(wù)器端編程
應(yīng)用程序
Java為什么能成功
系統(tǒng)能更易于表述和理解
最大程度上利用類庫(kù)
錯(cuò)誤處理
編寫大項(xiàng)目
Java還是C++?
總結(jié)
「讀書筆記」Thinking in Java 3rd Edition - 2: Everything is an Object