Двойная отправка в Фаро
Может ли кто-нибудь объяснить процесс двойной отправки в Pharo 4.0 с Smalltalk? Я новичок в Smalltalk, и мне трудно понять эту концепцию, поскольку она реализована в Java совершенно иначе, чем в Smalltalk. Будет очень полезно, если кто-нибудь сможет объяснить это на примере.
1 ответ
По сути, идея в том, что у вас есть метод:
#addInteger:
который знает, как добавить целые числа,#addFloat:
который знает, как добавить поплавки,- и так далее…
Сейчас в Integer
класс, который вы определяете +
как:
+ otherObject
otherObject addInteger: self
в Float
Вы определяете это как:
+ otherObject
otherObject addFloat: self
Таким образом, вам нужно только отправить +
к объекту, а затем он попросит получателя добавить его с требуемым методом.
Другая стратегия заключается в использовании #adaptTo:andSend:
методы. Например +
в Point
класс определяется как:
+ arg
arg isPoint ifTrue: [^ (x + arg x) @ (y + arg y)].
^ arg adaptToPoint: self andSend: #+
Который сначала проверяет, является ли аргумент Point, а если нет, просит аргумент адаптироваться к Point и отправлять какой-либо символ (операцию), это сохраняет некоторое дублирование методов, которые должны выполнить несколько иную операцию.
Collection
реализует метод следующим образом:
adaptToPoint: rcvr andSend: selector
^ self collect: [:element | rcvr perform: selector with: element]
а также Number
реализует это так:
adaptToPoint: rcvr andSend: selector
^ rcvr perform: selector with: self@self
Обратите внимание, что во избежание явной проверки типов мы могли бы определить этот метод в Point
Сам так:
adaptToPoint: rcvr andSend: selector
^ (x perform: selector with: arg x) @ (y perform: selector with: arg y)
Вы можете увидеть больше примеров в этой презентации: http://www.slideshare.net/SmalltalkWorld/stoop-302double-dispatch