類(1)

2018-02-24 15:48 更新

類,這個詞如果是你第一次聽到,把它作為一個單獨的名詞,總感覺怪怪的,因為在漢語體系中,很常見的是說“鳥類”、“人類”等詞語,而單獨說“類”,總感覺前面缺點修飾成分。其實,它對應(yīng)的是英文單詞class,“類”是這個class翻譯過來的,你就把它作為一個翻譯術(shù)語吧。

除了“類”這個術(shù)語,從現(xiàn)在開始,還要經(jīng)常提到一個OOP,即面向?qū)ο缶幊蹋ɑ蛘摺懊嫦驅(qū)ο蟪绦蛟O(shè)計”)。

為了理解類和OOP,需要對一些枯燥的名詞有了解。

術(shù)語

必須了解這些術(shù)語的基本含義,因為后面經(jīng)常用到。下面的術(shù)語定義均來自維基百科。

問題空間

定義:

問題空間是問題解決者對一個問題所達到的全部認識狀態(tài),它是由問題解決者利用問題所包含的信息和已貯存的信息主動地構(gòu)成的。

一個問題一般有下面三個方面來定義:

  • 初始狀態(tài)——一開始時的不完全的信息或令人不滿意的狀況;
  • 目標狀態(tài)——你希望獲得的信息或狀態(tài);
  • 操作——為了從初始狀態(tài)邁向目標狀態(tài),你可能采取的步驟。

這三個部分加在一起定義了問題空間(problem space)。

對象

定義:

對象(object),臺灣譯作物件,是面向?qū)ο螅∣bject Oriented)中的術(shù)語,既表示客觀世界問題空間(Namespace)中的某個具體的事物,又表示軟件系統(tǒng)解空間中的基本元素。

把object翻譯為“對象”,是比較抽象的。因此,有人認為,不如翻譯為“物件”更好。因為“物件”讓人感到一種具體的東西。

這種看法在某些語言中是非常適合的。但是,在Python中,則無所謂,不管怎樣,python中的一切都是對象,不管是字符串、函數(shù)、模塊還是類,都是對象?!叭f物皆對象”。

都是對象有什么優(yōu)勢嗎?太有了。這說明python天生就是OOP的。也說明,python中的所有東西,都能夠進行拼湊組合應(yīng)用,因為對象就是可以拼湊組合應(yīng)用的。

對于對象這個東西,OOP大師Grandy Booch的定義,應(yīng)該是權(quán)威的,相關(guān)定義的內(nèi)容包括:

  • 對象:一個對象有自己的狀態(tài)、行為和唯一的標識;所有相同類型的對象所具有的結(jié)構(gòu)和行為在他們共同的類中被定義。
  • 狀態(tài)(state):包括這個對象已有的屬性(通常是類里面已經(jīng)定義好的)在加上對象具有的當前屬性值(這些屬性往往是動態(tài)的)
  • 行為(behavior):是指一個對象如何影響外界及被外界影響,表現(xiàn)為對象自身狀態(tài)的改變和信息的傳遞。
  • 標識(identity):是指一個對象所具有的區(qū)別于所有其它對象的屬性。(本質(zhì)上指內(nèi)存中所創(chuàng)建的對象的地址)

大師的話的確有水平,聽起來非常高深。不過,初學者可能理解起來就有點麻煩了。我就把大師的話化簡一下,但是化簡了之后可能在嚴謹性上就不足了,我想對于初學者來講,應(yīng)該是影響不很大的。隨著學習和時間的深入,就更能理解大師的嚴謹描述了。

簡化之,對象應(yīng)該具有屬性(就是上面的狀態(tài),因為屬性更常用)、方法(就是上面的行為,方法跟常被使用)和標識。因為標識是內(nèi)存中自動完成的,所以,平時不用怎么管理它。主要就是屬性和方法。

為了體現(xiàn)“深入淺出”的道理,還是講故事吧。

既然萬物都是對象,那么,某個具體的人也是對象,這是當然的事情。假設(shè)這個具體的人就是德藝雙馨的蒼老師,她是一個對象。這個蒼老師具有哪些特征呢?我錯了,寫到這里發(fā)現(xiàn)不能用蒼老師為對象的例子,因為容易讓讀者不專心學習了。我換一個吧,以某個王美女為對象說明(這個王美女完全是虛構(gòu)的,請不要對號入座,更不要想入非非,如果雷同,純屬巧合)。

王美女這個對象具有某些特征,眼睛,大;腿,長;皮膚,白。當然,既然是美女,肯定還有別的顯明特征,讀者可以自己假設(shè)去。如果用“對象”的術(shù)語來說明,就說這些特征都是她的屬性。也就是說屬性是一個對象做具有的特征,或曰:是什么。

王美女除了具有上面的特征之外,她還能做一些事情,比如她能唱歌、會吹拉彈唱等。這些都是她能夠做的事情。用“對象”的術(shù)語來說,就是她的“方法”。即方法就是對象能夠做什么。

任何一個對象都要包括這兩部分:屬性(是什么)和方法(能做什么)。

面向?qū)ο?/h3>

定義:

面向?qū)ο蟪绦蛟O(shè)計(英語:Object-oriented programming,縮寫:OOP)是一種程序設(shè)計范型,同時也是一種程序開發(fā)的方法。對象指的是類的實例。它將對象作為程序的基本單元,將程序和數(shù)據(jù)封裝其中,以提高軟件的重用性、靈活性和擴展性。

面向?qū)ο蟪绦蛟O(shè)計可以看作一種在程序中包含各種獨立而又互相調(diào)用的對象的思想,這與傳統(tǒng)的思想剛好相反:傳統(tǒng)的程序設(shè)計主張將程序看作一系列函數(shù)的集合,或者直接就是一系列對電腦下達的指令。面向?qū)ο蟪绦蛟O(shè)計中的每一個對象都應(yīng)該能夠接受數(shù)據(jù)、處理數(shù)據(jù)并將數(shù)據(jù)傳達給其它對象,因此它們都可以被看作一個小型的“機器”,即對象。

目前已經(jīng)被證實的是,面向?qū)ο蟪绦蛟O(shè)計推廣了程序的靈活性和可維護性,并且在大型項目設(shè)計中廣為應(yīng)用。 此外,支持者聲稱面向?qū)ο蟪绦蛟O(shè)計要比以往的做法更加便于學習,因為它能夠讓人們更簡單地設(shè)計并維護程序,使得程序更加便于分析、設(shè)計、理解。反對者在某些領(lǐng)域?qū)Υ擞枰苑裾J。

當我們提到面向?qū)ο蟮臅r候,它不僅指一種程序設(shè)計方法。它更多意義上是一種程序開發(fā)方式。在這一方面,我們必須了解更多關(guān)于面向?qū)ο笙到y(tǒng)分析和面向?qū)ο笤O(shè)計(Object Oriented Design,簡稱OOD)方面的知識。

下面再引用一段來自維基百科中關(guān)于OOP的歷史。

面向?qū)ο蟪绦蛟O(shè)計的雛形,早在1960年的Simula語言中即可發(fā)現(xiàn),當時的程序設(shè)計領(lǐng)域正面臨著一種危機:在軟硬件環(huán)境逐漸復(fù)雜的情況下,軟件如何得到良好的維護?面向?qū)ο蟪绦蛟O(shè)計在某種程度上通過強調(diào)可重復(fù)性解決了這一問題。20世紀70年代的Smalltalk語言在面向?qū)ο蠓矫婵胺Q經(jīng)典——以至于30年后的今天依然將這一語言視為面向?qū)ο笳Z言的基礎(chǔ)。

計算機科學中對象和實例概念的最早萌芽可以追溯到麻省理工學院的PDP-1系統(tǒng)。這一系統(tǒng)大概是最早的基于容量架構(gòu)(capability based architecture)的實際系統(tǒng)。另外1963年Ivan Sutherland的Sketchpad應(yīng)用中也蘊含了同樣的思想。對象作為編程實體最早是于1960年代由Simula 67語言引入思維。Simula這一語言是奧利-約翰·達爾和克利斯登·奈加特在挪威奧斯陸計算機中心為模擬環(huán)境而設(shè)計的。(據(jù)說,他們是為了模擬船只而設(shè)計的這種語言,并且對不同船只間屬性的相互影響感興趣。他們將不同的船只歸納為不同的類,而每一個對象,基于它的類,可以定義它自己的屬性和行為。)這種辦法是分析式程序的最早概念體現(xiàn)。在分析式程序中,我們將真實世界的對象映射到抽象的對象,這叫做“模擬”。Simula不僅引入了“類”的概念,還應(yīng)用了實例這一思想——這可能是這些概念的最早應(yīng)用。

20世紀70年代施樂PARC研究所發(fā)明的Smalltalk語言將面向?qū)ο蟪绦蛟O(shè)計的概念定義為,在基礎(chǔ)運算中,對對象和消息的廣泛應(yīng)用。Smalltalk的創(chuàng)建者深受Simula 67的主要思想影響,但Smalltalk中的對象是完全動態(tài)的——它們可以被創(chuàng)建、修改并銷毀,這與Simula中的靜態(tài)對象有所區(qū)別。此外,Smalltalk還引入了繼承性的思想,它因此一舉超越了不可創(chuàng)建實例的程序設(shè)計模型和不具備繼承性的Simula。此外,Simula 67的思想亦被應(yīng)用在許多不同的語言,如Lisp、Pascal。

面向?qū)ο蟪绦蛟O(shè)計在80年代成為了一種主導(dǎo)思想,這主要應(yīng)歸功于C++——C語言的擴充版。在圖形用戶界面(GUI)日漸崛起的情況下,面向?qū)ο蟪绦蛟O(shè)計很好地適應(yīng)了潮流。GUI和面向?qū)ο蟪绦蛟O(shè)計的緊密關(guān)聯(lián)在Mac OS X中可見一斑。Mac OS X是由Objective-C語言寫成的,這一語言是一個仿Smalltalk的C語言擴充版。面向?qū)ο蟪绦蛟O(shè)計的思想也使事件處理式的程序設(shè)計更加廣泛被應(yīng)用(雖然這一概念并非僅存在于面向?qū)ο蟪绦蛟O(shè)計)。一種說法是,GUI的引入極大地推動了面向?qū)ο蟪绦蛟O(shè)計的發(fā)展。

蘇黎世聯(lián)邦理工學院的尼克勞斯·維爾特和他的同事們對抽象數(shù)據(jù)和模塊化程序設(shè)計進行了研究。Modula-2將這些都包括了進去,而Oberon則包括了一種特殊的面向?qū)ο蠓椒ā煌赟malltalk與C++。

面向?qū)ο蟮奶匦砸脖患尤肓水敃r較為流行的語言:Ada、BASIC、Lisp、Fortran、Pascal以及種種。由于這些語言最初并沒有面向?qū)ο蟮脑O(shè)計,故而這種糅合常常會導(dǎo)致兼容性和維護性的問題。與之相反的是,“純正的”面向?qū)ο笳Z言卻缺乏一些程序員們賴以生存的特性。在這一大環(huán)境下,開發(fā)新的語言成為了當務(wù)之急。作為先行者,Eiffel成功地解決了這些問題,并成為了當時較受歡迎的語言。

在過去的幾年中,Java語言成為了廣為應(yīng)用的語言,除了它與C和C++語法上的近似性。Java的可移植性是它的成功中不可磨滅的一步,因為這一特性,已吸引了龐大的程序員群的投入。

在最近的計算機語言發(fā)展中,一些既支持面向?qū)ο蟪绦蛟O(shè)計,又支持面向過程程序設(shè)計的語言悄然浮出水面。它們中的佼佼者有Python、Ruby等等。

正如面向過程程序設(shè)計使得結(jié)構(gòu)化程序設(shè)計的技術(shù)得以提升,現(xiàn)代的面向?qū)ο蟪绦蛟O(shè)計方法使得對設(shè)計模式的用途、契約式設(shè)計和建模語言(如UML)技術(shù)也得到了一定提升。

列位看官,當您閱讀到這句話的時候,我就姑且認為您已經(jīng)對面向?qū)ο笥辛艘粋€模糊的認識了。那么,類和OOP有什么關(guān)系呢?

定義:

在面向?qū)ο蟪淌皆O(shè)計,類(class)是一種面向?qū)ο笥嬎銠C編程語言的構(gòu)造,是創(chuàng)建對象的藍圖,描述了所創(chuàng)建的對象共同的屬性和方法。

類的更嚴格的定義是由某種特定的元數(shù)據(jù)所組成的內(nèi)聚的包。它描述了一些對象的行為規(guī)則,而這些對象就被稱為該類的實例。類有接口和結(jié)構(gòu)。接口描述了如何通過方法與類及其實例互操作,而結(jié)構(gòu)描述了一個實例中數(shù)據(jù)如何劃分為多個屬性。類是與某個層的對象的最具體的類型。類還可以有運行時表示形式(元對象),它為操作與類相關(guān)的元數(shù)據(jù)提供了運行時支持。

支持類的編程語言在支持與類相關(guān)的各種特性方面都多多少少有一些微妙的差異。大多數(shù)都支持不同形式的類繼承。許多語言還支持提供封裝性的特性,比如訪問修飾符。類的出現(xiàn),為面向?qū)ο缶幊痰娜齻€最重要的特性(封裝性,繼承性,多態(tài)性),提供了實現(xiàn)的手段。

看到這里,看官或許有一個認識,要OOP編程,就得用到類。可以這么說,雖然不是很嚴格。但是,反過來就不能說了。不是說用了類就一定是OOP。

編寫類

首先要明確,類是對某一群具有同樣屬性和方法的對象的抽象。比如這個世界上有很多長翅膀并且會飛的生物,于是聰明的人們就將它們統(tǒng)一稱為“鳥”——這就是一個類,雖然它也可以稱作“鳥類”。

還是以美女為例子,因為這個例子不僅能閱讀本課程不犯困,還能興趣昂然。

要定義類,就要抽象,找出共同的方面。

class 美女:        #用class來聲明,后面定義的是一個類
    pass

好,現(xiàn)在就從這里開始,編寫一個類,不過這次我們暫時不用python,而是用偽代碼,當然,這個代碼跟python相去甚遠。如下:

class 美女:
    胸圍 = 90
    腰圍 = 58
    臀圍 = 83
    皮膚 = white
    唱歌()
    做飯()

定義了一個名稱為“美女”的類,其中我約定,沒有括號的是屬性,帶有括號的是方法。這個類僅僅是對美女的通常抽象,并不是某個具體美女.

對于一個具體的美女,比如前面提到的蒼老師或者王美女,她們都是上面所定義的“美女”那個類的具體化,這在編程中稱為“美女類”的實例。

王美女 = 美女()

我用這樣一種表達方式,就是將“美女類”實例化了,對“王美女”這個實例,就可以具體化一些屬性,比如胸圍;還可以具體實施一些方法,比如做飯。通常可以用這樣一種方式表示:

a = 王美女.胸圍

用點號.的方式,表示王美女胸圍的屬性,得到的變量a就是90.另外,還可以通過這種方式給屬性賦值,比如

王美女.皮膚 = black

這樣,這個實例(王美女)的皮膚就是黑色的了。

通過實例,也可以訪問某個方法,比如:

王美女.做飯()

這就是在執(zhí)行一個方法,讓王美女這個實例做飯。現(xiàn)在也比較好理解了,只有一個具體的實例才能做飯。

至此,你是否對類和實例,類的屬性和方法有初步理解了呢?如果沒有理解,請用蒼老師實例化美女類,你一定能理解的。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號