Smalltalk 如何为实例创建方法编写doubledispatch?
实例创建方法,如Smalltalk 如何为实例创建方法编写doubledispatch?,smalltalk,pharo,squeak,Smalltalk,Pharo,Squeak,实例创建方法,如 ClassName new 为了帮助了解一些细节 我们可以在抽象类中编写a=算术方法 然后在子类中双重分派它们 我们可以在实例创建中使用它吗 我试过新的,但失败了。导致一些预定义的基本新方法。双重分派在新建的情况下没有意义。双重分派背后的思想是,您不能仅通过分派给接收者来确定正确的行为。(单个)参数的类型对选择(调度)的行为具有相同的影响。换句话说,双分派只有在方法有参数时才有意义,new是一元的,而不是一元的 也就是说,您当然可以实现自己的new方法来覆盖股票默认继承的方法
ClassName new
为了帮助了解一些细节
我们可以在抽象类中编写a=算术方法
然后在子类中双重分派它们
我们可以在实例创建中使用它吗
我试过新的,但失败了。导致一些预定义的基本新方法。
双重分派
在新建
的情况下没有意义。双重分派背后的思想是,您不能仅通过分派给接收者来确定正确的行为。(单个)参数的类型对选择(调度)的行为具有相同的影响。换句话说,双分派只有在方法有参数时才有意义,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:)双重分派的关键点是,通过交换主要消息的接收方和参数,您可以第二次调用虚拟调用,然后您可以根据消息接收方及其参数选择方法。因此,您需要有带参数的消息 这里是一个典型的双重分派示例:加法整数和浮点,并执行适当的转换
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
正如Esteban所指出的,在Squeak/Pharo风格中,每个新成员都发送一个initialize,这是一个很好的行为,因此它应该是basicNew initialize。
MyClass class>>newWith: arg
arg newFromMyClass: aClass