理解面向?qū)ο?/h2>
大家一定注意到在面試時(shí)總是會(huì)被問(wèn)一遍又一遍的同樣的陳詞濫調(diào)的問(wèn)題,例如:
- 你覺(jué)得五年后你自己是什么樣子(你對(duì)五年后的自己有什么期待)?
- 你認(rèn)為什么是你最大的弱點(diǎn)?
同樣面試程序開(kāi)發(fā)工作,面向?qū)ο笠彩歉哳l考點(diǎn)之一。
1. 什么是面向?qū)ο螅?/h3>
1.1 面向?qū)ο蟮臍v史
面向?qū)ο笫且环N編程范式(也叫方法論、思維方法等)。目前大部分語(yǔ)言都是支持多種范式的,包括面向?qū)ο筮@種范式。
- 1950
objects 和 oriented 等技術(shù)名詞在 MIT 里出現(xiàn),概念尚未明確。ALGOL 語(yǔ)言里有面向?qū)ο蟮囊恍┰缙谛螒B(tài),如消息、方法、成員函數(shù)等 - 1960
Simula 語(yǔ)言初步實(shí)現(xiàn)了面向?qū)ο笏枷?,一些重要的概念得以?shí)現(xiàn),如類(lèi)、對(duì)象、繼承、動(dòng)態(tài)綁定等。
不過(guò) Simula 沒(méi)有實(shí)現(xiàn) private 和 public 等訪問(wèn)修飾器. - 1970
Smalltalk 出現(xiàn)。Smalltalk 主要是受 Simula 啟發(fā)。Lisp 又受 Smalltalk 的影響,也開(kāi)始接納面向?qū)ο笏枷?,最終導(dǎo)致了 Flavors(首個(gè)引入 mixin 的語(yǔ)言)、CommonLoops(支持多繼承),而這兩門(mén)語(yǔ)言有導(dǎo)致了『Common Lisp 對(duì)象系統(tǒng)』的出現(xiàn)。 - 1980
1981 年 Adele Goldberg 撰文將 Smalltalk 和面向?qū)ο缶幊探榻B給更多的人。1986 年第一屆『面向?qū)ο缶幊谭鍟?huì)』舉辦,吸引了一千多人參加。期間,C++ 和 Objective-C 受此影響誕生。 - 1990
面向?qū)ο笏枷氡粡V泛接納,甚至成為主流編程思想,尤其是用戶(hù)界面編程領(lǐng)域。事件驅(qū)動(dòng)編程在它的帶領(lǐng)下也開(kāi)始變得流行。一些原本不支持面向?qū)ο蟮恼Z(yǔ)言也開(kāi)始引入面向?qū)ο螅˙ASIC、Pascal),并引發(fā)了一些問(wèn)題。一些從一開(kāi)始就支持面向?qū)ο螅仓С忠郧暗倪^(guò)程式編程的語(yǔ)言被發(fā)明出來(lái),如 Python 和 Ruby。最重要的商業(yè)化面向?qū)ο笳Z(yǔ)言是 Sun 公司開(kāi)發(fā)的 Java 語(yǔ)言,以及微軟公司開(kāi)發(fā)的 C# 和 VB.NET。
1.2 面向?qū)ο笳Z(yǔ)言的分類(lèi)
- 純面向?qū)ο笳Z(yǔ)言:一切都是對(duì)象,包括數(shù)字、字符串也是對(duì)象,如 Python、Ruby、Scala、Smalltalk
- 完全支持面向?qū)ο螅仓С诌^(guò)程式,如 Java、C++、C#
- 本來(lái)不支持面向?qū)ο?,后?lái)加上的,如 PHP、Perl
= 看起來(lái)像面向?qū)ο?,但沒(méi)有完全使用面向?qū)ο螅ū热缁谠蛠?lái)模擬面向?qū)ο螅篔avaScript、Lua
2. 面向?qū)ο笥心男┨匦裕?/h3>
提到面向?qū)ο蟮奶匦?,有八個(gè)字自然而然浮現(xiàn)在我們腦海中年蹦出來(lái)了,那就是【封裝】【抽象】【繼承】【多態(tài)】
2.1 封裝
假設(shè)我們有一個(gè)程序,擁有一些邏輯不同的對(duì)象,它們根據(jù)程序中定義的規(guī)則相互通信。
我們通過(guò)實(shí)現(xiàn)封裝讓每個(gè)對(duì)象在類(lèi)中保持其私有狀態(tài)時(shí),其他對(duì)象無(wú)法直接訪問(wèn)此狀態(tài)。與此同時(shí),他們只能調(diào)用一個(gè)公共函數(shù)列表,也就是方法。對(duì)象通過(guò)自己管理自己的狀態(tài)(除非明確允許,否則沒(méi)有其他類(lèi)可以觸及它)。如果要與對(duì)象通信,則應(yīng)使用提供的方法。
假設(shè)我們正在構(gòu)建一個(gè)小游戲。有人,還有一只貓,貓餓了,人就需要喂貓,人喂了貓,貓饑餓感就減少了。
我們想要使用面向?qū)ο蟮乃枷脒M(jìn)行封裝,因此我們將所有“貓”的狀態(tài)與動(dòng)作封裝到Cat類(lèi)中。它可能看起來(lái)像這樣:
人可以喂貓,但人無(wú)法直接改變貓的饑餓程度。
在這里,貓的“狀態(tài)”的情緒,饑餓和能量是私人變量。它還有一個(gè)私有方法meow()。貓可以隨時(shí)調(diào)用它(喵喵叫),人(其他類(lèi))不能告訴貓什么時(shí)候喵喵叫。
人和貓都可以做的是在公共方法sleep(),play()和feed()中定義。他們每個(gè)都以某種方式修改內(nèi)部狀態(tài),并可能調(diào)用meow()。因此,進(jìn)行了私有狀態(tài)和公共方法之間的綁定?!@是封裝。
2.2 抽象
抽象可以被認(rèn)為是封裝的延伸M
在實(shí)際的應(yīng)用中,程序通常非常大。并且單獨(dú)的對(duì)象相互通信很多。因此,不斷在這個(gè)維護(hù)這樣的代碼,并在其上增加新的功能特性是很復(fù)雜的,常常是牽一發(fā)而動(dòng)全身。抽象就是為了緩解這個(gè)問(wèn)題。
應(yīng)用抽象意味著對(duì)象只對(duì)外部公開(kāi)使用它的方法,而隱藏對(duì)象內(nèi)部實(shí)現(xiàn)細(xì)節(jié)。
抽象就跟我們平時(shí)手機(jī)一樣,手機(jī)組成很復(fù)雜,有硬件有軟件。但使用它確很簡(jiǎn)單。我們只需觸摸即可與手機(jī)進(jìn)行互動(dòng)。在我們觸摸的時(shí)候手機(jī)做了什么?我們不必知道(也就是隱藏了實(shí)現(xiàn)細(xì)節(jié)),軟件更新(也就是抽象內(nèi)部邏輯更改)很少影響我們的使用。
2.3 繼承
理解封裝和抽象幫助我們能夠開(kāi)發(fā)和維護(hù)一個(gè)大的代碼庫(kù)。但是在實(shí)際面向?qū)ο缶幊讨?,我們常常?huì)遇到一些對(duì)象,他們有著相同的邏輯,但是又不盡相同。
我們是把他們隔離開(kāi)為兩個(gè)獨(dú)立的,各自維護(hù)自身邏輯狀態(tài)的兩個(gè)類(lèi)嗎?但是他們的確有千絲萬(wàn)縷的聯(lián)系。
如果我們能夠重用通用邏輯并將各自獨(dú)特的邏輯提取出來(lái)就好了。
實(shí)現(xiàn)這一目標(biāo)的一種方法是繼承
這意味著我們通過(guò)(父)類(lèi)派生來(lái)創(chuàng)建(子)類(lèi)。這樣,我們就擁有了一個(gè)層次結(jié)構(gòu)。子類(lèi)重用父類(lèi)的所有字段和方法(公共部分),并且可以實(shí)現(xiàn)它自己的(獨(dú)特部分)。
例如:私人教師是教師的一種,而任何教師屬于人。如果我們的計(jì)劃需要管理公立和私立教師,還有其他類(lèi)型的人,比如學(xué)生,我們可以通過(guò)繼承實(shí)現(xiàn)。這樣,每個(gè)類(lèi)都擁有了父類(lèi)的邏輯與特點(diǎn),并且可以實(shí)現(xiàn)與維護(hù)自己獨(dú)特的邏輯與狀態(tài)。
2.4 多態(tài)
通過(guò)繼承,我們可以實(shí)現(xiàn)父類(lèi)和子類(lèi)。假設(shè)我們有一個(gè)父類(lèi)和一些繼承它的子類(lèi)。有時(shí)我們想要使用一個(gè)集合(例如一個(gè)列表,它包含所有這些類(lèi)的混合);或者我們有一個(gè)為父類(lèi)實(shí)現(xiàn)的方法,但我們也想將它用于子類(lèi)。這時(shí)可以通過(guò)使用多態(tài)來(lái)解決。
簡(jiǎn)而言之,多態(tài)性提供了一種使用與其父類(lèi)完全相同的類(lèi)的方法,因此不會(huì)混淆混合類(lèi)型。但是每個(gè)子類(lèi)都有自己的實(shí)現(xiàn)特點(diǎn)。
這通常通過(guò)定義要重用的(父)接口來(lái)實(shí)現(xiàn),它實(shí)現(xiàn)了一堆常用方法。然后,每個(gè)子類(lèi)能夠?qū)崿F(xiàn)這些方法的自己版本。
例如:動(dòng)物能夠發(fā)出聲音,貓和狗繼承動(dòng)物的類(lèi),也具有發(fā)出聲音的特性。但是貓發(fā)出的聲音為"喵喵喵",狗發(fā)出的聲音的為"汪汪汪"。在程序中,他們都使用say()這個(gè)從animal繼承來(lái)的方法,但是貓和狗有自己不同的實(shí)現(xiàn)。
3. 古老的面向?qū)ο蟆猄malltalk
3.1 安裝
gst-win - Windows installer for gst
下載安裝,然后打開(kāi) cmd 打開(kāi),輸入 gst 即可開(kāi)始使用 Smalltalk。
3.2 語(yǔ)法
官方教程
使用字符串單引號(hào),雙引號(hào)是注釋?zhuān)灰褂谩?/p>
(1 + 2) * 3 // 9
'Hello, world' printNl // 輸出 Hello world
數(shù)組
x := Array new: 20
x at: 1
x at: 1 put: 99
(x at: 1) + 1
Set
使用英文句號(hào)斷句
x := Set new
x add: 5. x add: 7. x add: 'foo'
x remove: 5
x includes: 7
字典
y := Dictionary new
y at: 'One' put: 1
y at: 'Two' put: 2
y at: 1 put: 'One'
y at: 2 put: 'Two'
y at: 1
y at: 'Two'
y
y! 用于刪除 y 的值
y
3.3 Smalltalk中的對(duì)象
在Smalltalk中所有的東西都是對(duì)象,或者應(yīng)該被當(dāng)作對(duì)象處理。例如下面的表達(dá)式:
2 + 3.
應(yīng)當(dāng)被理解為:向?qū)ο?發(fā)送消息+,參數(shù)為對(duì)象3。
(15 * 19) + (37 squared)
可以理解為:向15發(fā)送消息'*',參數(shù)為19;向37發(fā)送消息squared;最后向15*19的結(jié)果發(fā)送消息'+',參數(shù)為37 squared的結(jié)果。