董保華 6527 字 1個月前

◎第一章 人工智能語言 麵向對象語言

(3 / 6)
登入後報錯可獲 3天VIP 免廣告——立即登入

2.Dynamicdispatch(按照對象運行時真正類型來決定)

(按,熟悉C++的朋友們一定微笑了,這再簡單不過了。)

staticdispatch沒什麼可說的。

dynamicdispatch卻有一個有趣的屬性。那就是,subsumption一定不能影響對象的狀態。如果在subsumption的時候,改變了這個對象的狀態,比如象C++中的對象切片,那麼動態解析的方法就可能會失敗。

好在,這個屬性無論對語義,還是對效率,都是很有好處的。

(按,C++中的objectslicing會把新的對象的vptr初始化成它自己類型的vtable指針,所以不存在動態解析的問題。但實際上,對象切片根本不能叫做subsumption。

具體語言實現中,如C++,雖然subsumption不會改變對象內部的狀態,但指針的值卻是可能會變化的。這也是一個讓人討厭的東西,但C++vtable的方案卻隻能這樣。有一種變種的vtable方法,可以避免指針的變化,也更高效。會在另外的文章中闡述這種方法。)

關於類型信息

雖然subsumption並不改變對象的狀態,在一些語言裡(如Java),它甚至沒有任何運行時開銷。但是,它卻使丟掉了一些靜態的類型信息。

比如說,有一個類型InstanceTypeOf(Object),而Object類裡沒有定義任何屬性和方法。又有一個類MyObject,它繼承自Object。那麼當把MyObject的對象當作InstanceTypeOf(Object)類型來處理的時候,就得到了一個什麼東西也沒有的沒用的空對象。

當然,如果考慮一個不那麼極端的情況,比如說,Object類裡麵定義了一個方法f,而MyObject對方法f做了重載,那麼,通過dynamicdispatch,還是可以間接地操作MyObject中的屬性和方法的。這也是麵向對象設計和編程的典型方法。

從一個purist的角度看,dynamicdispatch是唯一應該用來操作已經被subsumption忘掉的屬性和方法的東西。它優雅,安全,所有的榮耀都歸於dynamicdispatch!!!

不過,讓purist們失望的是,大部分語言還是提供了一些在運行時檢查對象類型,並從而操作被subsumption遺忘的屬性和方法。這種方法一般被叫做RTTI(RunTimeTypeIdentification)。如C++中的dynamic_cast,或Java中的instanceof.

實事求是地說,RTTI是有用的。但因為一些理論上以及方法論上的原因,它被認為是破壞了麵向對象的純潔性。

首先,它破壞了抽象,使一些本來不應該被使用的方法和屬性被不正確地使用。

其次,因為運行時類型的不確定性,它有效地把程序變得更脆弱。

第三點,也許是最重要的一點,它使程序缺乏擴展性。當加入了一個新的類型時,也許需要仔細閱讀dynamic_cast或instanceof的代碼,必要時改動它們,以保證這個新的類型的加入不會導致問題。

很多人一提到RTTI,總是側重於它的運行時的開銷。但是,相比於方法論上的缺點,這點運行時的開銷真是無足輕重的。

而在purist的框架中(按,吸一口氣,目視遠方,做深沉狀),新的子類的加入並不需要改動已有的代碼。

這是一個非常好的優點,尤其是當並不擁有全部源代碼時。

總的來說,雖然RTTI(也叫typecase)似乎是不可避免的一種特性,但因為它的方法論上的一些缺點,它必須被非常謹慎的使用。今天麵向對象語言的類型係統中的很多東西就是產生於避免RTTI的各種努力。

比如有些複雜的類型係統中可以在參數和返回值上使用Self類型來避免RTTI.這點後麵會介紹到。

協變,反協變和壓根兒不變

協變,反協變和壓根兒不變(Covarance,ContravarianceandInvariance)

在下麵的幾個小節裡,來介紹一種避免RTTI的類型技術。在此之前,先來介紹“協變”,“反協變”和“壓根兒不變”的概念。

協變

首先,來看一個Pair類型:A*B

這個類型支持一個getA()的操作以返回這個Pair中的A元素。

給定一個A’<:A,那麼,可以說A’*B<:A*B。

為什麼呢?可以用Subsumption的屬性加以證明:

假設有一個A’*B類型的對象a’*b,這裡,a’:A’,b:B,a’*b<:A’*B

那麼,因為,A’<:A,從subsumption,可以知道a’:A,getA():A所以,a’*b<:A*B

這樣,就定義A*B這個類型對於A是協變的。

w t . p o o在盡節章說小新最

。的變協是也B於對B*A明證以可也,理同

:的義定樣這是ecnairavoC,說點一規正

,麼那。的成合組T型類過通是L型類,裡這,)T(L定給

。的變協T對是L說就麼那,)2T(L:<)1T(L出推夠能2T:<1T果如

變協反

)A>-B:f即,潔簡更許也義定的egaugnallanoitcnuf用(;)bB(fA:數函個一看請

?呢係關epytbus的樣麼什有間之A>-’B和A’B個一定給,麼那

。AA>-B,明證以可

。導推做再不,幅篇於基

。的變協反是型類數參的數函,以所

:的樣這是義定的點規正的ecnairavartnoC

,麼那。的成合組T型類過通是L型類,裡這,)T(L定給

。的變協反T對是L說就麼那,)1T(L:<)2T(L出推夠能2T:<1T果如

。的變協是型類回返的數函,明證以可,樣同

兒根壓


✅ 付款功能已修復,現在可以正常購買了 — 支援信用卡 · Apple Pay · Google Pay · WebATM · ATM 轉帳
😤 廣告總在最入戲的時候跳出來?
月付 $5 USD,升級 VIP 後全站所有頁面廣告立即全關——
不是只有這本書,是整個 oop.tw 每一頁、每一章,從此一路讀到底不被打斷。 $5 USD ≈ 一杯珍奶的錢,換一整個月零廣告清爽閱讀 · 隨時可取消
✅ 全站廣告全關 ✅ 工口專區全本解鎖 ✅ 月卡 $5 USD · 季卡 $13 USD · 年卡 $45 USD
⭐ 登入 / 免費註冊後升級
加我 LINE 好友,分享好書不錯過
第一時間獲得新書推薦、書單更新通知
立即加入
上一頁 書頁/目錄
/ 6 頁
下一頁
為本書評分(每位讀者可評一次,提交後無法修改
發表評論
匿名讀者 身份發表
讀者評論