2013-06-20 2 views
2
метод

создания экземпляра, какКак написать дубликат для метода создания экземпляра?

ClassName new 

Чтобы помочь с некоторыми деталями,

мы могли бы написать = арифметический метод в абстрактном классе,

затем doubledispatch их в подклассах.

мы можем использовать это, например, создание?

Я пробовал новый, но он терпит неудачу. Приводит к некоторому предопределенному базовому новому методу.

ответ

6

Double Dispatch в действительности не имеет смысла в случае new. Идея двойной отправки заключается в том, что вы не можете определить правильное поведение, отправив только получателю. Тип (одиночный) аргумент имеет равное влияние на то, какое поведение выбрано (отправлено). Другими словами, двойная отправка имеет смысл только в том случае, если у вас есть аргументы в ваших методах, но унарные, это не так.

Это означает, что вы можете, конечно, реализовать свой собственный метод new, который переопределяет унаследованный по умолчанию вариант по умолчанию. И вы можете заставить его делать всевозможные интересные вещи. Обычно для проверки того, какой подкласс является подходящим, необходимо выполнить некоторую проверку среды.

AbstractClass>>>new 
    ^self platform = #unix 
     ifTrue: [SubclassThatLeveragesUnix basicNew] 
     ifFalse: [CrappyPCSubclass basicNew] 

Обратите внимание, что мы используем basicNew здесь, а не new. Если вы использовали new, вам нужно либо реализовать различные переопределения в этих подклассах, иначе он просто наследует и повторно отправляет сообщение AbstractClass>>>new.

+1

Как отметил Эстебан, в вкусе Squeak/Pharo хорошо себя вести, что каждый новый посылает инициализацию, поэтому он будет basicNew инициализироваться. –

4

... или вы могли бы сделать что-то вроде:

AbstractClass class>>#new 
    ^(self platform concreteClassFor: self) basicNew initialize. 

, которая в основном та же идея, но без сослагательного наклонения :)

1

Ключевым моментом двойной отправки является то, что путем замены ресивера и аргумент первичного сообщения, вы вызываете второй раз виртуальный вызов, а затем получаете эффект выбора метода на основе приемника сообщения и его аргумента. Поэтому вам нужно иметь сообщение с аргументом.

Вот типичный пример двойной отправки: добавление целого числа и поплавка и выполнение адекватного преобразования.

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 ударит первый + на Integer, то sumFromInt: то +, то sumFromFloat. Обратите внимание, что у нас достаточно информации, поэтому мы могли бы сократить время вызова + +

Что показывает пример: во время первого вызова динамическое разрешение сообщений находит на методе (поэтому оно определяется как динамический случай), а затем путем замены аргумент и получатель, разрешение динамического сообщения выполняет другой случай, основанный на аргументе. Поэтому в конце вы получаете метод, выбранный с использованием двух объектов исходного вызова. Теперь о вашем вопросе: в сообщениях класса Pharo динамически просматриваются, поэтому вы можете внедрять методы создания экземпляров, используя двойную отправку без проблем, но цель неясна.

MyClass class>>newWith: arg 
    arg newFromMyClass: aClass