1.2 面向?qū)ο蟮拈_發(fā) (OOP: Object Oriented Programming)
1.2.1 面向?qū)ο蟪绦蛟O(shè)計模式
發(fā)明面向?qū)ο蟪绦蛟O(shè)計方法的主要出發(fā)點(diǎn)是彌補(bǔ)面向過程程序設(shè)計方法中的一些缺點(diǎn)。OOP把數(shù)據(jù)看作程序開發(fā)中的基本元素,并且不允許它們在系統(tǒng)中自由流動。它將數(shù)據(jù)和操作這些數(shù)據(jù)的函數(shù)緊密的連結(jié)在一起,并保護(hù)數(shù)據(jù)不會被外界的函數(shù)意外的改變。OOP允許我們將問題分解為一系列實(shí)體——這些實(shí)體被稱為對象(object),然后圍繞這些實(shí)體建立數(shù)據(jù)和函數(shù)。面向?qū)ο蟪绦蛟O(shè)計中的數(shù)據(jù)和函數(shù)的組織結(jié)構(gòu)如圖所示。
?
1.2.2 什么是面向?qū)ο蟪绦蛟O(shè)計?
? ? ? ?面向?qū)ο蟪绦蛟O(shè)計(OOP)技術(shù)汲取了結(jié)構(gòu)化程序設(shè)計中好的思想,并將這些思想與一些新的、強(qiáng)大的理念相結(jié)合,從而給你的程序設(shè)計工作提供了一種全新的方法。通常,在面向?qū)ο蟮某绦蛟O(shè)計風(fēng)格中,你會將一個問題分解為一些相互關(guān)聯(lián)的子集,每個子集內(nèi)部都包含了相關(guān)的數(shù)據(jù)和函數(shù)。同時,你會以某種方式將這些子集分為不同等級,而一個對象就是已定義的某個類型的變量。當(dāng)你定義了一個對象,你就隱含的創(chuàng)建了一個新的數(shù)據(jù)類型。 1.2.3 面向?qū)ο蟪绦蛟O(shè)計中的基本概念 “面向?qū)ο蟆弊鳛橐粋€術(shù)語,在不同的人群中有著不同的解釋。因此,了解一些在面向?qū)ο蟪绦蛟O(shè)計中廣泛應(yīng)用的概念是必須的。本節(jié)我們討論以下這些內(nèi)容:
1、對象(Object)
2、類(Class)
?3、數(shù)據(jù)抽象(Data abstraction)
4、繼承(Inheritance)
5、動態(tài)綁定(Dynamic binding)
6、數(shù)據(jù)封裝(Data encapsulation)
7、多態(tài)性(Polymorphism)
8、消息傳遞(Message passing)
對象
在一個面向?qū)ο蟮南到y(tǒng)中,對象是運(yùn)行期的基本實(shí)體。它可以用來表示一個人或者說一個銀行帳戶,一張數(shù)據(jù)表格,或者其它什么需要被程序處理的東西。它也可以用來表示用戶定義的數(shù)據(jù),例如一個向量,時間或者列表。在面向?qū)ο蟪绦蛟O(shè)計中,問題的分析一般以對象及對象間的自然聯(lián)系為依據(jù)。如前所述,對象在內(nèi)存中占有一定空間,并且具有一個與之關(guān)聯(lián)的地址,就像Pascal中的record和C中的結(jié)構(gòu)一樣。 當(dāng)一個程序運(yùn)行時,對象之間通過互發(fā)消息來相互作用。例如,程序中包含一個“customer”對象和一個“account”對象,而customer對象可能會向account對象發(fā)送一個消息,查詢其銀行帳目。每個對象都包含數(shù)據(jù)以及操作這些數(shù)據(jù)的代碼。即使不了解彼此的數(shù)據(jù)和代碼的細(xì)節(jié),對象之間依然可以相互作用,所要了解的只是對象能夠接受的消息的類型,以及對象返回的響應(yīng)的類型,雖然不同的人會以不同的方法實(shí)現(xiàn)它們。
類
我們剛才提到,對象包含數(shù)據(jù)以及操作這些數(shù)據(jù)的代碼。一個對象所包含的所有數(shù)據(jù)和代碼可以通過類來構(gòu)成一個用戶定義的數(shù)據(jù)類型。事實(shí)上,對象就是類類型(class type)的變量。一旦定義了一個類,我們就可以創(chuàng)建這個類的多個對象,每個對象與一組數(shù)據(jù)相關(guān),而這組數(shù)據(jù)的類型在類中定義。因此,一個類就是具有相同類型的對象的抽象。例如,芒果、蘋果和桔子都是fruit類的對象。類是用戶定義的數(shù)據(jù)類型,但在一個程序設(shè)計語言中,它和內(nèi)建的數(shù)據(jù)類型行為相同。比如創(chuàng)建一個類對象的語法和創(chuàng)建一個整數(shù)對象的語法一模一樣。如果fruit被定義為一個
類,那么語句 fruit mango; 就創(chuàng)建了一個fruit類的對象mango。 數(shù)據(jù)抽象和封裝
把數(shù)據(jù)和函數(shù)包裝在一個單獨(dú)的單元(稱為類)的行為稱為封裝。數(shù)據(jù)封裝是類的最典型特點(diǎn)。數(shù)據(jù)不能被外界訪問,只能被封裝在同一個類中的函數(shù)訪問。這些函數(shù)提供了對象數(shù)據(jù)和程序之間的接口。避免數(shù)據(jù)被程序直接訪問的概念被稱為“數(shù)據(jù)隱藏”。 抽象指僅表現(xiàn)核心的特性而不描述背景細(xì)節(jié)的行為。類使用了抽象的概念,并且被定義為一系列抽象的屬性如尺寸、重量和價格,以及操作這些屬性的函數(shù)。類封裝了將要被創(chuàng)建的對象的所有核心屬性。因?yàn)轭愂褂昧藬?shù)據(jù)抽象的概念,所以它們被稱為抽象數(shù)據(jù)類型(ADT)。
封裝
封裝機(jī)制將數(shù)據(jù)和代碼捆綁到一起,避免了外界的干擾和不確定性。它同樣允許創(chuàng)建對象。簡單的說,一個對象就是一個封裝了數(shù)據(jù)和操作這些數(shù)據(jù)的代碼的邏輯實(shí)體。 在一個對象內(nèi)部,某些代碼和(或)某些數(shù)據(jù)可以是私有的,不能被外界訪問。通過這種方式,對象對內(nèi)部數(shù)據(jù)提供了不同級別的保護(hù),以防止程序中無關(guān)的部分意外的改變或錯誤的使用了對象的私有部分。
繼承
繼承是可以讓某個類型的對象獲得另一個類型的對象的屬性的方法。它支持按級分類的概念。例如,知更鳥屬于飛鳥類,也屬于鳥類。就像圖5中描繪的那樣,這種分類的原則是,每一個子類都具有父類的公共特性。
?
在OOP中,繼承的概念很好的支持了代碼的重用性(reusability),也就是說,我們可以向一個已經(jīng)存在的類中添加新的特性,而不必改變這個類。這可以通過從這個已存在的類派生一個新類來實(shí)現(xiàn)。這個新的類將具有原來那個類的特性,以及新的特性。而繼承機(jī)制的魅力和強(qiáng)大就在于它允許程序員利用已經(jīng)存在的類(接近需要,而不是完全符合需要的類),并且可以以某種方式修改這個類,而不會影響其它的東西。 注意,每個子類只定義那些這個類所特有的特性。而如果沒有按級分類,每類都必須顯式的定義它所有的特性。
多態(tài)
多態(tài)是OOP的另一個重要概念。多態(tài)的意思是事物具有不同形式的能力。舉個例子,對于不同的實(shí)例,某個操作可能會有不同的行為。這個行為依賴于所要操作數(shù)據(jù)的類型。比如說加法操作,如果操作的數(shù)據(jù)是數(shù),它對兩個數(shù)求和。如果操作的數(shù)據(jù)是字符串,則它將連接兩個字符串。 圖6演示了一個函數(shù)處理不同數(shù)量、不同類型的參數(shù)。就像某個單詞在不同的上下文中具有不同的含義
?
多態(tài)機(jī)制使具有不同內(nèi)部結(jié)構(gòu)的對象可以共享相同的外部接口。這意味著,雖然針對不同對象的具體操作不同,但通過一個公共的類,它們(那些操作)可以通過相同的方式予以調(diào)用。多態(tài)在實(shí)現(xiàn)繼承的過程中被廣泛應(yīng)用。 面向?qū)ο蟪绦蛟O(shè)計語言支持多態(tài),術(shù)語稱之為“one interface multiple method(一個接口,多個實(shí)現(xiàn))”。簡單來說,多態(tài)機(jī)制允許通過相同的接口引發(fā)一組相關(guān)但不相同的動作,通過這種方式,可以減少代碼的復(fù)雜度。在某個特定的情況下應(yīng)該作出怎樣的動作,這由編譯器決定,而不需要程序員手工干預(yù)。 在多函數(shù)程序中,許多重要的數(shù)據(jù)被聲明為全局變量,這樣它們才可以被所有的函數(shù)訪問。每個函數(shù)又可以具有它自己的局部變量。全局變量很容易被某個函數(shù)不經(jīng)意之間改變。而在一個大程序中,很難分辨每個函數(shù)都使用了哪些變量。如果我們需要修改某個外部數(shù)據(jù)的結(jié)構(gòu),我們就要修改所有訪問這個數(shù)據(jù)的函數(shù)。這很容易導(dǎo)致bug的產(chǎn)生
在結(jié)構(gòu)化程序設(shè)計中,另一個嚴(yán)重的缺陷是不能很好的模擬真實(shí)世界的問題。這是因?yàn)楹瘮?shù)都是面向過程的,而不是真正的對應(yīng)于問題中的各個元素。 面向過程的程序設(shè)計的一些特點(diǎn)如下:
?強(qiáng)調(diào)做(算法);
?大程序被分隔為許多小程序,這些小程序稱為函數(shù); ?大多數(shù)函數(shù)共享全局?jǐn)?shù)據(jù);
?數(shù)據(jù)開放的由一個函數(shù)流向另一個函數(shù)。函數(shù)把數(shù)據(jù)從一種形式轉(zhuǎn)換為另一種形式。 采用由上至下的程序設(shè)計方法。
動態(tài)綁定
綁定指的是將一個過程調(diào)用與相應(yīng)代碼鏈接起來的行為。動態(tài)綁定的意思是,與給定的過程調(diào)用相關(guān)聯(lián)的代碼只有在運(yùn)行期才可知。它與多態(tài)和繼承的聯(lián)系極為緊密。一個多態(tài)引用的函數(shù)調(diào)用決定于這個引用的動態(tài)類型。 考慮圖6中的“draw”方法。通過繼承,每個對象都具備了這個過程。但是,對于不同的對象它的算法是不同的,因此,draw過程必須在每一個類中重新定義。在運(yùn)行期,當(dāng)前引用對象所對應(yīng)的代碼將被調(diào)用。
消息傳遞
一個面向?qū)ο蟮某绦蛴稍S多對象組成,這些對象之間需要相互溝通。因此,在面向?qū)ο蟪绦蛟O(shè)計語言中,程序設(shè)計的主要步驟如下: 1、創(chuàng)建類,這些類定義了對象及其行為; 2、由類定義創(chuàng)建對象; 3、建立對象之間的通訊。 對象之間通過收發(fā)信息相互溝通,這一點(diǎn)類似于人與人之間的信息傳遞。信息傳遞的概念使得真實(shí)世界的直接模擬更易于和建立系統(tǒng)交流。 對于某個特定對象來說,消息就是請求執(zhí)行某個過程,因此,消息的接收對象會調(diào)用一個函數(shù)(過程),以產(chǎn)生預(yù)期的結(jié)果。傳遞的消息的內(nèi)容包括接收消息的對象的名字,需要調(diào)用的函數(shù)的名字,以及必要的信息。 對象就有一個生命周期。它們可以被創(chuàng)建和銷毀。只要對象正處于其生存期,就可以與其進(jìn)行通訊。
評論
查看更多