實例創建方法,像如何爲實例創建方法編寫doubledispatch?
ClassName new
要使用一些細節幫助,
,我們可以在抽象類寫=算術方法,
然後doubledispatch他們的子類。
我們可以在創建實例時使用它嗎?
我嘗試了新的但它失敗。引出一些預定義的基本新方法。
實例創建方法,像如何爲實例創建方法編寫doubledispatch?
ClassName new
要使用一些細節幫助,
,我們可以在抽象類寫=算術方法,
然後doubledispatch他們的子類。
我們可以在創建實例時使用它嗎?
我嘗試了新的但它失敗。引出一些預定義的基本新方法。
Double Dispatch
在new
的情況下沒有意義。雙派遣背後的想法是,你不能通過僅派發給接收者來確定正確的行爲。 (單個)參數的類型對選擇(分派)哪種行爲具有相同的效果。換句話說,如果你的方法有參數,雙重調度纔有意義,new
是一元的,但它不是。
也就是說,你當然可以實現你自己的new
方法來覆蓋股票默認繼承的方法。你可以讓它做各種有趣的事情。通常做一些環境檢查來確定哪個子類是合適的。
AbstractClass>>>new
^self platform = #unix
ifTrue: [SubclassThatLeveragesUnix basicNew]
ifFalse: [CrappyPCSubclass basicNew]
注意,我們使用basicNew
這裏,而不是new
。如果您使用的是new
,則需要在這些子類中實施不同的覆蓋,否則它只會繼承並重新發送AbstractClass>>>new
消息。
...或者你可以這樣做:
AbstractClass class>>#new
^(self platform concreteClassFor: self) basicNew initialize.
這基本上是相同的想法,但沒有IFS :)
雙調度的關鍵點是通過交換接收器和主要消息的參數,您再次調用虛擬調用,然後獲得基於消息接收方及其參數選擇方法的效果。因此你需要有參數的消息。
以下是double dispatch的一個典型示例:添加整數和浮點數並執行適當的轉換。
Integer>>+ arg
^arg sumFromInteger: self
Float>>+ arg
^arg sumFromFloat: self
Integer>>sumFromInteger: anInt
<primitive adding to ints>
Integer>>sumFromFloat: aFloat
^self asFloat + aFloat
Float>>sumFromFloat: aFloat
<primitive adding two floats>
Float>>sumFromInteger: anInt
^self + anInt asFloat
查閱1 + 1.0將達到第一+整型然後sumFromInt:然後+然後sumFromFloat。請注意,我們有足夠的信息,因此我們可以快捷地調用第二個+,
示例顯示的是,在第一次調用期間,動態消息解析在方法上找到(因此定義爲動態情況),然後通過交換參數和接收方,動態消息解析基於arg執行另一個案例。所以最後你會得到一個使用原始調用的兩個對象選擇的方法。 現在你的問題:在Pharo類的消息動態查找,所以你可以實現使用雙派遣實例創建方法沒有問題,但目標不明確。
MyClass class>>newWith: arg
arg newFromMyClass: aClass
正如Esteban所指出的,在Squeak/Pharo風格中,每個新發送一個初始化都是很好的表現,所以它將是基本的新初始化。 –