天天看點

關于面向對象的一些思考

  适才在寫python程式,寫一個對象的集合容器類,糾結要不要實作疊代器方法來允許for in語句。突然發現,for a in obj和for a in obj.l 給人很大的不同感。我并沒有一下子得到明确的思緒(這也不構成問題,僅僅是一個“問題”),想到在哲學群裡的争論和一些以前的思考,決定寫一篇部落格。

  其實寫到這裡,我已經有些思路了,那就是python不隐藏屬性,做不到很好的封裝——不過更多地,我也沒有刻意區分過“狀态”和“屬性”(也許“字段”和“屬性”對某些人更好些),即一個對象中儲存的值在機能上的意義。如果實作疊代方法,那麼該類對外就和清單沒什麼關系。而假如用obj.l的方式,那麼這個類僅僅是“清單的容器“(而非自定義對象的容器),清單這個本該多餘的概念始終是暴露的,它應該作為隐式的“狀态”,而不是供外部通路的“屬性”。——在語言層面,python的對象隻有屬性,但(我覺得)也許某些程式員……會下意識地區分二者,并使用python的“假私有屬性”特性——用雙下劃線開頭的名稱命名(用作狀态的)屬性。

  而之前還有一次對于面向對象的思考,和“模闆繼承”相關。python的format函數可以很友善地作為模闆,假如我們需要一個網頁模闆——即用來生成隻有少量幾處不同的字元串,我們可以用 待format的 字元串來表示它,然後傳入各個值,比如:

  而“模闆繼承”引出了哲學問題。假如:

  這個模闆顯然“應當”從之前的模闆“繼承”而來。而實作這個“繼承”,可以僅僅擴充format函數,添加這樣一條規則:

新的format函數對于不比對的項,不執行替換

  我們可以預計它的行為:

  這個新的format函數就很有趣了,它擁有普通format的功能!也就是說,假如說普通format“可以将一個模闆執行個體化”,那麼對于新的format,“它既可以将一個模闆執行個體化,也可以将一個模闆繼承出新模闆”。這時候我開始質疑自己了,究竟什麼是執行個體化和繼承?

  另外這裡給出一個新format函數的粗略實作(笑):

  我想到了另一個問題:一個無需替換的字元串,固然可以看成一個執行個體,但何嘗不也是一個類呢?這個派生出的類,把基類的初始化參數填滿了,不需要其他參數了而已。——接觸過偏函數,甚至柯裡化的朋友,可以借此比對一下。

  我在面向對象有關的書裡,看到過(大緻)這樣的例子:“水果是一個類,而蘋果,梨等等是水果類派生出的執行個體。”仔細想想便會發現,實際中蘋果、梨也是類,而具體的某個蘋果,某個梨才“稱得上”執行個體——但是倒不是我批駁這個舉例,執行個體化就是個騙局!(笑)試想在計算機中,我們是如何描述一個“執行個體”的?一些具體的資料 ,是吧?但是,從哲學上說,任意多的描述都不能指定出一個具體的東西,它依然是一堆描述,而一堆描述正是指定了一個“類”!

  從來都沒有執行個體化,隻有繼承。——然而學程式設計不須學哲學,姑且相信執行個體化并不造成任何實質問題,除了在極少情況下面對“蘋果是對象還是類”時會有些困惑……

  不過很多情況下,類已經寫死在語言裡了。隻能說,把我們要泛化的一層看成執行個體化即可……或者用lua的面向對象系統,或者根本不使用現成的類型系統來表示實際的類(Unity的ECS模型似乎有這種哲學)

  但是從字元串到類,這個比對妥當麼?類的繼承讓功能越來越多,字元串和偏函數卻讓功能越來越少。類的繼承添加了功能。

  不過仔細想想也不沖突,添加功能也“使自由度變低了”。使用一個類在邏輯上也不能使用子類的功能。

  ………………(我該在自己的語言裡實作類來體驗一下)

  還有一次思考,是在和别人百般解釋不清某個抽象概念,感慨自然語言之其妙。請看如下表述:

  “蘋果可以吃”

  是不是很奇妙?“蘋果”是一個類,但可以吃的東西自然是某個執行個體(現實中的“執行個體”還是比較妥的),而此表述沒人會誤會。但是——

  “夢是假的”

  我是由怎樣的表述而了解“夢本身是真的”這一情況的?我該如何表達?

  邏輯果然不是人該幹的事。

(2018-8-12 于地球)(完)

繼續閱讀