類(lèi),這個(gè)詞如果是你第一次聽(tīng)到,把它作為一個(gè)單獨(dú)的名詞,總感覺(jué)怪怪的,因?yàn)樵跐h語(yǔ)體系中,很常見(jiàn)的是說(shuō)“鳥(niǎo)類(lèi)”、“人類(lèi)”等詞語(yǔ),而單獨(dú)說(shuō)“類(lèi)”,總感覺(jué)前面缺點(diǎn)修飾成分。其實(shí),它對(duì)應(yīng)的是英文單詞class,“類(lèi)”是這個(gè)class翻譯過(guò)來(lái)的,你就把它作為一個(gè)翻譯術(shù)語(yǔ)吧。
除了“類(lèi)”這個(gè)術(shù)語(yǔ),從現(xiàn)在開(kāi)始,還要經(jīng)常提到一個(gè)OOP,即面向?qū)ο缶幊蹋ɑ蛘摺懊嫦驅(qū)ο蟪绦蛟O(shè)計(jì)”)。
為了理解類(lèi)和OOP,需要對(duì)一些枯燥的名詞有了解。
必須了解這些術(shù)語(yǔ)的基本含義,因?yàn)楹竺娼?jīng)常用到。下面的術(shù)語(yǔ)定義均來(lái)自維基百科。
定義:
問(wèn)題空間是問(wèn)題解決者對(duì)一個(gè)問(wèn)題所達(dá)到的全部認(rèn)識(shí)狀態(tài),它是由問(wèn)題解決者利用問(wèn)題所包含的信息和已貯存的信息主動(dòng)地構(gòu)成的。
一個(gè)問(wèn)題一般有下面三個(gè)方面來(lái)定義:
這三個(gè)部分加在一起定義了問(wèn)題空間(problem space)。
定義:
對(duì)象(object),臺(tái)灣譯作物件,是面向?qū)ο螅∣bject Oriented)中的術(shù)語(yǔ),既表示客觀世界問(wèn)題空間(Namespace)中的某個(gè)具體的事物,又表示軟件系統(tǒng)解空間中的基本元素。
把object翻譯為“對(duì)象”,是比較抽象的。因此,有人認(rèn)為,不如翻譯為“物件”更好。因?yàn)椤拔锛弊屓烁械揭环N具體的東西。
這種看法在某些語(yǔ)言中是非常適合的。但是,在Python中,則無(wú)所謂,不管怎樣,python中的一切都是對(duì)象,不管是字符串、函數(shù)、模塊還是類(lèi),都是對(duì)象。“萬(wàn)物皆對(duì)象”。
都是對(duì)象有什么優(yōu)勢(shì)嗎?太有了。這說(shuō)明python天生就是OOP的。也說(shuō)明,python中的所有東西,都能夠進(jìn)行拼湊組合應(yīng)用,因?yàn)閷?duì)象就是可以拼湊組合應(yīng)用的。
對(duì)于對(duì)象這個(gè)東西,OOP大師Grandy Booch的定義,應(yīng)該是權(quán)威的,相關(guān)定義的內(nèi)容包括:
大師的話(huà)的確有水平,聽(tīng)起來(lái)非常高深。不過(guò),初學(xué)者可能理解起來(lái)就有點(diǎn)麻煩了。我就把大師的話(huà)化簡(jiǎn)一下,但是化簡(jiǎn)了之后可能在嚴(yán)謹(jǐn)性上就不足了,我想對(duì)于初學(xué)者來(lái)講,應(yīng)該是影響不很大的。隨著學(xué)習(xí)和時(shí)間的深入,就更能理解大師的嚴(yán)謹(jǐn)描述了。
簡(jiǎn)化之,對(duì)象應(yīng)該具有屬性(就是上面的狀態(tài),因?yàn)閷傩愿S茫⒎椒ǎň褪巧厦娴男袨?,方法跟常被使用)和?biāo)識(shí)。因?yàn)闃?biāo)識(shí)是內(nèi)存中自動(dòng)完成的,所以,平時(shí)不用怎么管理它。主要就是屬性和方法。
為了體現(xiàn)“深入淺出”的道理,還是講故事吧。
既然萬(wàn)物都是對(duì)象,那么,某個(gè)具體的人也是對(duì)象,這是當(dāng)然的事情。假設(shè)這個(gè)具體的人就是德藝雙馨的蒼老師,她是一個(gè)對(duì)象。這個(gè)蒼老師具有哪些特征呢?我錯(cuò)了,寫(xiě)到這里發(fā)現(xiàn)不能用蒼老師為對(duì)象的例子,因?yàn)槿菀鬃屪x者不專(zhuān)心學(xué)習(xí)了。我換一個(gè)吧,以某個(gè)王美女為對(duì)象說(shuō)明(這個(gè)王美女完全是虛構(gòu)的,請(qǐng)不要對(duì)號(hào)入座,更不要想入非非,如果雷同,純屬巧合)。
王美女這個(gè)對(duì)象具有某些特征,眼睛,大;腿,長(zhǎng);皮膚,白。當(dāng)然,既然是美女,肯定還有別的顯明特征,讀者可以自己假設(shè)去。如果用“對(duì)象”的術(shù)語(yǔ)來(lái)說(shuō)明,就說(shuō)這些特征都是她的屬性。也就是說(shuō)屬性是一個(gè)對(duì)象做具有的特征,或曰:是什么。。
王美女除了具有上面的特征之外,她還能做一些事情,比如她能唱歌、會(huì)吹拉彈唱等。這些都是她能夠做的事情。用“對(duì)象”的術(shù)語(yǔ)來(lái)說(shuō),就是她的“方法”。即方法就是對(duì)象能夠做什么。
任何一個(gè)對(duì)象都要包括這兩部分:屬性(是什么)和方法(能做什么)。
定義:
面向?qū)ο蟪绦蛟O(shè)計(jì)(英語(yǔ):Object-oriented programming,縮寫(xiě):OOP)是一種程序設(shè)計(jì)范型,同時(shí)也是一種程序開(kāi)發(fā)的方法。對(duì)象指的是類(lèi)的實(shí)例。它將對(duì)象作為程序的基本單元,將程序和數(shù)據(jù)封裝其中,以提高軟件的重用性、靈活性和擴(kuò)展性。
面向?qū)ο蟪绦蛟O(shè)計(jì)可以看作一種在程序中包含各種獨(dú)立而又互相調(diào)用的對(duì)象的思想,這與傳統(tǒng)的思想剛好相反:傳統(tǒng)的程序設(shè)計(jì)主張將程序看作一系列函數(shù)的集合,或者直接就是一系列對(duì)電腦下達(dá)的指令。面向?qū)ο蟪绦蛟O(shè)計(jì)中的每一個(gè)對(duì)象都應(yīng)該能夠接受數(shù)據(jù)、處理數(shù)據(jù)并將數(shù)據(jù)傳達(dá)給其它對(duì)象,因此它們都可以被看作一個(gè)小型的“機(jī)器”,即對(duì)象。
目前已經(jīng)被證實(shí)的是,面向?qū)ο蟪绦蛟O(shè)計(jì)推廣了程序的靈活性和可維護(hù)性,并且在大型項(xiàng)目設(shè)計(jì)中廣為應(yīng)用。 此外,支持者聲稱(chēng)面向?qū)ο蟪绦蛟O(shè)計(jì)要比以往的做法更加便于學(xué)習(xí),因?yàn)樗軌蜃屓藗兏?jiǎn)單地設(shè)計(jì)并維護(hù)程序,使得程序更加便于分析、設(shè)計(jì)、理解。反對(duì)者在某些領(lǐng)域?qū)Υ擞枰苑裾J(rèn)。
當(dāng)我們提到面向?qū)ο蟮臅r(shí)候,它不僅指一種程序設(shè)計(jì)方法。它更多意義上是一種程序開(kāi)發(fā)方式。在這一方面,我們必須了解更多關(guān)于面向?qū)ο笙到y(tǒng)分析和面向?qū)ο笤O(shè)計(jì)(Object Oriented Design,簡(jiǎn)稱(chēng)OOD)方面的知識(shí)。
下面再引用一段來(lái)自維基百科中關(guān)于OOP的歷史。
面向?qū)ο蟪绦蛟O(shè)計(jì)的雛形,早在1960年的Simula語(yǔ)言中即可發(fā)現(xiàn),當(dāng)時(shí)的程序設(shè)計(jì)領(lǐng)域正面臨著一種危機(jī):在軟硬件環(huán)境逐漸復(fù)雜的情況下,軟件如何得到良好的維護(hù)?面向?qū)ο蟪绦蛟O(shè)計(jì)在某種程度上通過(guò)強(qiáng)調(diào)可重復(fù)性解決了這一問(wèn)題。20世紀(jì)70年代的Smalltalk語(yǔ)言在面向?qū)ο蠓矫婵胺Q(chēng)經(jīng)典——以至于30年后的今天依然將這一語(yǔ)言視為面向?qū)ο笳Z(yǔ)言的基礎(chǔ)。
計(jì)算機(jī)科學(xué)中對(duì)象和實(shí)例概念的最早萌芽可以追溯到麻省理工學(xué)院的PDP-1系統(tǒng)。這一系統(tǒng)大概是最早的基于容量架構(gòu)(capability based architecture)的實(shí)際系統(tǒng)。另外1963年Ivan Sutherland的Sketchpad應(yīng)用中也蘊(yùn)含了同樣的思想。對(duì)象作為編程實(shí)體最早是于1960年代由Simula 67語(yǔ)言引入思維。Simula這一語(yǔ)言是奧利-約翰·達(dá)爾和克利斯登·奈加特在挪威奧斯陸計(jì)算機(jī)中心為模擬環(huán)境而設(shè)計(jì)的。(據(jù)說(shuō),他們是為了模擬船只而設(shè)計(jì)的這種語(yǔ)言,并且對(duì)不同船只間屬性的相互影響感興趣。他們將不同的船只歸納為不同的類(lèi),而每一個(gè)對(duì)象,基于它的類(lèi),可以定義它自己的屬性和行為。)這種辦法是分析式程序的最早概念體現(xiàn)。在分析式程序中,我們將真實(shí)世界的對(duì)象映射到抽象的對(duì)象,這叫做“模擬”。Simula不僅引入了“類(lèi)”的概念,還應(yīng)用了實(shí)例這一思想——這可能是這些概念的最早應(yīng)用。
20世紀(jì)70年代施樂(lè)PARC研究所發(fā)明的Smalltalk語(yǔ)言將面向?qū)ο蟪绦蛟O(shè)計(jì)的概念定義為,在基礎(chǔ)運(yùn)算中,對(duì)對(duì)象和消息的廣泛應(yīng)用。Smalltalk的創(chuàng)建者深受Simula 67的主要思想影響,但Smalltalk中的對(duì)象是完全動(dòng)態(tài)的——它們可以被創(chuàng)建、修改并銷(xiāo)毀,這與Simula中的靜態(tài)對(duì)象有所區(qū)別。此外,Smalltalk還引入了繼承性的思想,它因此一舉超越了不可創(chuàng)建實(shí)例的程序設(shè)計(jì)模型和不具備繼承性的Simula。此外,Simula 67的思想亦被應(yīng)用在許多不同的語(yǔ)言,如Lisp、Pascal。
面向?qū)ο蟪绦蛟O(shè)計(jì)在80年代成為了一種主導(dǎo)思想,這主要應(yīng)歸功于C++——C語(yǔ)言的擴(kuò)充版。在圖形用戶(hù)界面(GUI)日漸崛起的情況下,面向?qū)ο蟪绦蛟O(shè)計(jì)很好地適應(yīng)了潮流。GUI和面向?qū)ο蟪绦蛟O(shè)計(jì)的緊密關(guān)聯(lián)在Mac OS X中可見(jiàn)一斑。Mac OS X是由Objective-C語(yǔ)言寫(xiě)成的,這一語(yǔ)言是一個(gè)仿Smalltalk的C語(yǔ)言擴(kuò)充版。面向?qū)ο蟪绦蛟O(shè)計(jì)的思想也使事件處理式的程序設(shè)計(jì)更加廣泛被應(yīng)用(雖然這一概念并非僅存在于面向?qū)ο蟪绦蛟O(shè)計(jì))。一種說(shuō)法是,GUI的引入極大地推動(dòng)了面向?qū)ο蟪绦蛟O(shè)計(jì)的發(fā)展。
蘇黎世聯(lián)邦理工學(xué)院的尼克勞斯·維爾特和他的同事們對(duì)抽象數(shù)據(jù)和模塊化程序設(shè)計(jì)進(jìn)行了研究。Modula-2將這些都包括了進(jìn)去,而Oberon則包括了一種特殊的面向?qū)ο蠓椒ā煌赟malltalk與C++。
面向?qū)ο蟮奶匦砸脖患尤肓水?dāng)時(shí)較為流行的語(yǔ)言:Ada、BASIC、Lisp、Fortran、Pascal以及種種。由于這些語(yǔ)言最初并沒(méi)有面向?qū)ο蟮脑O(shè)計(jì),故而這種糅合常常會(huì)導(dǎo)致兼容性和維護(hù)性的問(wèn)題。與之相反的是,“純正的”面向?qū)ο笳Z(yǔ)言卻缺乏一些程序員們賴(lài)以生存的特性。在這一大環(huán)境下,開(kāi)發(fā)新的語(yǔ)言成為了當(dāng)務(wù)之急。作為先行者,Eiffel成功地解決了這些問(wèn)題,并成為了當(dāng)時(shí)較受歡迎的語(yǔ)言。
在過(guò)去的幾年中,Java語(yǔ)言成為了廣為應(yīng)用的語(yǔ)言,除了它與C和C++語(yǔ)法上的近似性。Java的可移植性是它的成功中不可磨滅的一步,因?yàn)檫@一特性,已吸引了龐大的程序員群的投入。
在最近的計(jì)算機(jī)語(yǔ)言發(fā)展中,一些既支持面向?qū)ο蟪绦蛟O(shè)計(jì),又支持面向過(guò)程程序設(shè)計(jì)的語(yǔ)言悄然浮出水面。它們中的佼佼者有Python、Ruby等等。
正如面向過(guò)程程序設(shè)計(jì)使得結(jié)構(gòu)化程序設(shè)計(jì)的技術(shù)得以提升,現(xiàn)代的面向?qū)ο蟪绦蛟O(shè)計(jì)方法使得對(duì)設(shè)計(jì)模式的用途、契約式設(shè)計(jì)和建模語(yǔ)言(如UML)技術(shù)也得到了一定提升。
列位看官,當(dāng)您閱讀到這句話(huà)的時(shí)候,我就姑且認(rèn)為您已經(jīng)對(duì)面向?qū)ο笥辛艘粋€(gè)模糊的認(rèn)識(shí)了。那么,類(lèi)和OOP有什么關(guān)系呢?
定義:
在面向?qū)ο蟪淌皆O(shè)計(jì),類(lèi)(class)是一種面向?qū)ο笥?jì)算機(jī)編程語(yǔ)言的構(gòu)造,是創(chuàng)建對(duì)象的藍(lán)圖,描述了所創(chuàng)建的對(duì)象共同的屬性和方法。
類(lèi)的更嚴(yán)格的定義是由某種特定的元數(shù)據(jù)所組成的內(nèi)聚的包。它描述了一些對(duì)象的行為規(guī)則,而這些對(duì)象就被稱(chēng)為該類(lèi)的實(shí)例。類(lèi)有接口和結(jié)構(gòu)。接口描述了如何通過(guò)方法與類(lèi)及其實(shí)例互操作,而結(jié)構(gòu)描述了一個(gè)實(shí)例中數(shù)據(jù)如何劃分為多個(gè)屬性。類(lèi)是與某個(gè)層的對(duì)象的最具體的類(lèi)型。類(lèi)還可以有運(yùn)行時(shí)表示形式(元對(duì)象),它為操作與類(lèi)相關(guān)的元數(shù)據(jù)提供了運(yùn)行時(shí)支持。
支持類(lèi)的編程語(yǔ)言在支持與類(lèi)相關(guān)的各種特性方面都多多少少有一些微妙的差異。大多數(shù)都支持不同形式的類(lèi)繼承。許多語(yǔ)言還支持提供封裝性的特性,比如訪(fǎng)問(wèn)修飾符。類(lèi)的出現(xiàn),為面向?qū)ο缶幊痰娜齻€(gè)最重要的特性(封裝性,繼承性,多態(tài)性),提供了實(shí)現(xiàn)的手段。
看到這里,看官或許有一個(gè)認(rèn)識(shí),要OOP編程,就得用到類(lèi)??梢赃@么說(shuō),雖然不是很?chē)?yán)格。但是,反過(guò)來(lái)就不能說(shuō)了。不是說(shuō)用了類(lèi)就一定是OOP。
首先要明確,類(lèi)是對(duì)某一群具有同樣屬性和方法的對(duì)象的抽象。比如這個(gè)世界上有很多長(zhǎng)翅膀并且會(huì)飛的生物,于是聰明的人們就將它們統(tǒng)一稱(chēng)為“鳥(niǎo)”——這就是一個(gè)類(lèi),雖然它也可以稱(chēng)作“鳥(niǎo)類(lèi)”。
還是以美女為例子,因?yàn)檫@個(gè)例子不僅能閱讀本課程不犯困,還能興趣昂然。
要定義類(lèi),就要抽象,找出共同的方面。
class 美女: #用class來(lái)聲明,后面定義的是一個(gè)類(lèi)
pass
好,現(xiàn)在就從這里開(kāi)始,編寫(xiě)一個(gè)類(lèi),不過(guò)這次我們暫時(shí)不用python,而是用偽代碼,當(dāng)然,這個(gè)代碼跟python相去甚遠(yuǎn)。如下:
class 美女:
胸圍 = 90
腰圍 = 58
臀圍 = 83
皮膚 = white
唱歌()
做飯()
定義了一個(gè)名稱(chēng)為“美女”的類(lèi),其中我約定,沒(méi)有括號(hào)的是屬性,帶有括號(hào)的是方法。這個(gè)類(lèi)僅僅是對(duì)美女的通常抽象,并不是某個(gè)具體美女.
對(duì)于一個(gè)具體的美女,比如前面提到的蒼老師或者王美女,她們都是上面所定義的“美女”那個(gè)類(lèi)的具體化,這在編程中稱(chēng)為“美女類(lèi)”的實(shí)例。
王美女 = 美女()
我用這樣一種表達(dá)方式,就是將“美女類(lèi)”實(shí)例化了,對(duì)“王美女”這個(gè)實(shí)例,就可以具體化一些屬性,比如胸圍;還可以具體實(shí)施一些方法,比如做飯。通??梢杂眠@樣一種方式表示:
a = 王美女.胸圍
用點(diǎn)號(hào).
的方式,表示王美女胸圍的屬性,得到的變量a就是90.另外,還可以通過(guò)這種方式給屬性賦值,比如
王美女.皮膚 = black
這樣,這個(gè)實(shí)例(王美女)的皮膚就是黑色的了。
通過(guò)實(shí)例,也可以訪(fǎng)問(wèn)某個(gè)方法,比如:
王美女.做飯()
這就是在執(zhí)行一個(gè)方法,讓王美女這個(gè)實(shí)例做飯?,F(xiàn)在也比較好理解了,只有一個(gè)具體的實(shí)例才能做飯。
至此,你是否對(duì)類(lèi)和實(shí)例,類(lèi)的屬性和方法有初步理解了呢?如果沒(méi)有理解,請(qǐng)用蒼老師實(shí)例化美女類(lèi),你一定能理解的。
更多建議: