1. 程式人生 > >關於面向對象的一些思考

關於面向對象的一些思考

bash 添加 有關 相關 類的繼承 函數 lse 實例 問題:

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

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


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

template = "<h1>Good {time}, {name}!</h1>"
print(template.format(time="night",name="Amy"))

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

template2 = "<h1>Good night, {name}!</h1>"

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

  • 新的format函數對於不匹配的項,不執行替換

  我們可以預計它的行為:

>>> "<h1>Good {time}, {name}!</h1>".format(time="night")
"<h1>Good night, {name}!</h1>"

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

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

def new_format(s,**d):
    class D:
        def __init__(self,d):self.__d = d
        def __getattr__(self,s):return self.__d.get(s,'{'+s+'}')
    s_ = '{0.'.join(s.split('{'))
    return s_.format(D(d))

template = "<h1>Good {time}, {name}!</h1>"  # test
print(new_format(template,time="night",name="Amy"))
print(new_format(template,time="night"))

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

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

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

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

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

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

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


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

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

  “夢是假的

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

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

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

關於面向對象的一些思考