編程基礎概念:面向對象編程

===》點我返回目錄《===

現在的世界,大家都用面向對象編程。這是結構化編程的基礎上進一步發展出來的。以前編程的範式是數據結構+算法,後來軟件規模越來越大,於是在一個程序裏面出現了成百上千個函數過程和數據結構,程序很不容易維護。於是人們就把程序分解成子程序,子程序裏面包含更小的組成部件,每個部件由一些數據結構及相關的算法組成。這些部件我們叫做對象。

按照這樣的觀點,程序由一堆對象及對象間的消息互動組成。聽起來好像很平常,甚至認爲很自然很理所當然。這個思想卻是一大進步。這個範式最後成爲主流,現在幾乎所有的系統都是按照這個範式構建的。

這個範式爲什麼好呢?理論上的研究表明,需求構成了“問題空間”,程序構成了“解決空間”,兩個空間的相似度決定了解決的困難度。傳統上,我們要解決一個問題,計算機給我們提供的卻是寄存器、內存、加法器這一類機器的概念術語,所以那個時候將問題空間映射到解決空間的時候很複雜。而面向對象事件驅動的模型,跟現實世界的問題空間有一定程度的相似度,我們能夠比較省力地進行映射,解決問題。這個現實世界,本就是一個一個主體客體構成,它們發生了什麼事情,本來就是通過消息傳遞方式聯繫在一起的。面向對象編程有一些新的術語,如類,對象/實例,消息,方法,屬性。我們後面會接觸到。

不過我們要了解,任何一種編程範式都是有侷限的,面向對象範式的缺點是過於強調名詞(對象),而把動詞(操作/算法)隱藏在名詞中沒有獨立抽象出來,遇到有些場景會設計得比較彆扭複雜。比如關係數據庫的場景,1970年代發展出來的關係理論非常強大,但是跟面向對象思想不是很兼容,在設計軟件的時候,我們被迫採用一種叫做ORM的方式進行映射,很複雜而且低效。我個人的觀點,關係數據庫是一種流,不是對象,應該採用代數演算來處理,我們的設計模式需要改變,要對等考慮對象、動作和關係。

Python支持多種類型的編程範式,例如過程式編程、函數式編程、面向對象編程,而且還可以融合多種類型的範式。我們後面寫的程序也是過程和對象編程混合的,都會介紹一點。

Python類的結構是:

class ClassName:

    <statement-1>

    .

    <statement-N>

類是相同對象的一個抽象,包含了屬性和方法,可以理解爲傳統編程中的變量和函數,也可以理解爲一個完成某功能的獨立程序單元。

類本身只是一個定義,運行的時候要根據這個類的定義生成一些實例去執行,這些實例也叫對象。對象裏面有自己的屬性和方法,兩個對象之間這些屬性的值是獨立的,互不干擾。

而一個類還可以有子類,子類繼承了父類的屬性和方法,之外還可以有自己特殊的方法和屬性。一個實際的系統都會構建一整套繼承體系,這也是面向對象編程的難點,不小心設計,很容易把體系構建得亂七八糟。所以,架構師一般會設計一些接口或者純粹虛的類,作爲對外的界面,然後構造一些抽象類進行基礎部分的實現,最後讓程序員實現具體的子類完成特定的業務邏輯。

在實際語言的實現中,除了常規的用實例去運行,還會提供類級別的運行,可以直接使用類裏面的變量和方法。

看一個例子:

class MyClass:

    i = 100 #類變量

    def __init__(self,initp): #構造方法

        self.i=initp #實例變量

    def test(): #類方法

        print(MyClass.i)

        return "test()"

    def method1(self): #實例方法

        return 'hello world'

測試一下:

x = MyClass(10) #創建一個類實例

y = MyClass(20)#創建另一個類實例

print(x.i) #x實例的變量i

print(y.i) #y實例的變量i

print(MyClass.i) #類變量i

print(MyClass.test()) #類方法test()

歷史上,好些科學家都爲面向對象編程貢獻了想法,所以我們不能確切地說誰發明了面向對象的概念。我這裏要提到的Alan Kay是比較出名的一個,他1960年代就提出了這個想法,發明了Smalltalk語言,爲圖形界面做出了先驅性貢獻,於2003年獲Turing獎。他最有名的一句名言是“The best way to predict the future is to invent it.”。

 

(Alan Kay,1940.5.17 - ,圖片來源:維基百科)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章