2015-06-15 12 views
6

Könnte jemand bitte den Prozess des doppelten Versands in Pharo 4.0 mit Smalltalk erklären? Ich bin neu in Smalltalk und habe Schwierigkeiten, das Konzept zu verstehen, da es in Java sehr anders als in Smalltalk implementiert ist. Es wird sehr hilfreich sein, wenn jemand es mit einem Beispiel erklären könnte.Doppelter Versand in Pharo

Antwort

9

Im Grunde ist die Idee, dass Sie Methode haben:

  • #addInteger:, die weiß, wie ganze Zahlen zu addieren,
  • #addFloat:, die weiß, wie man schwimmt,
  • und so weiter ...
hinzufügen

Jetzt in Integer Klasse definieren Sie + als:

+ otherObject 

    otherObject addInteger: self 

in Float Sie definieren es mögen:

+ otherObject 

    otherObject addFloat: self 

Auf diese Weise können nur + an ein Objekt senden müssen und dann wird es den Empfänger bitten, es mit der erforderlichen Methode hinzuzufügen. Eine andere Strategie besteht darin, die Methoden #adaptTo:andSend: zu verwenden. Zum Beispiel + in Point Klasse ist wie folgt definiert:

+ arg 

    arg isPoint ifTrue: [^ (x + arg x) @ (y + arg y)]. 
^arg adaptToPoint: self andSend: #+ 

Was ist zuerst überprüft, ob das Argument ein Punkt ist, und wenn es nicht ist, fragt das Argument anzupassen einige Symbole (Betrieb) zu Punkt und zu senden, dies einige spart Duplizierung der Methoden, die eine etwas andere Operation ausführen müssen.

Collection implementiert das Verfahren wie folgt aus:

adaptToPoint: rcvr andSend: selector 

^self collect: [:element | rcvr perform: selector with: element] 

und Number implementiert es wie folgt aus:

adaptToPoint: rcvr andSend: selector 

^rcvr perform: selector with: [email protected] 

Hinweis, dass explizite Typprüfung zu vermeiden, wird diese Methode in der Point definieren könnte sich auf diese Weise:

adaptToPoint: rcvr andSend: selector 

^(x perform: selector with: arg x) @ (y perform: selector with: arg y) 

Sie können weitere Beispiele in dieser Präsentation sehen: http://www.slideshare.net/SmalltalkWorld/stoop-302double-dispatch

+1

Danke, das macht jetzt vollkommen Sinn. Grundsätzlich rufen Sie eine generische Methode auf und definieren sie in allen zugehörigen Klassen. Aber innerhalb der spezifischen Klassen, zu denen die Argumente eigentlich gehen sollen, setzen Sie eine bestimmte Implementierung mit den spezifischen Argumenten. Wenn der Methodenaufruf bestimmt wird, wird anhand des Selektors und Empfängers des Objekts herausgefunden, welche Methode aufgerufen werden soll. – ruhi