实例创建方法,如
ClassName new
为了提供一些细节,
我们可以在抽象类中编写一个算术方法,
然后在子类中双重发送它们。
我们可以在实例创建中使用它吗?
我尝试了新功能,但失败了。导致一些预定义的基本新方法。
答案 0 :(得分:6)
Double Dispatch
案例中, new
没有任何意义。双重调度背后的想法是,您无法通过仅调度接收器来确定正确的行为。 (单个)参数的类型对选择(调度)的行为具有相同的影响。换句话说,双重调度只有在您的方法有参数时才有意义,new
是一元的,而不是。
也就是说,您当然可以实现自己的new
方法,该方法会覆盖库存默认继承的方法。你可以让它做各种有趣的事情。通常会进行某种环境检查以确定适合的子类。
AbstractClass>>>new
^self platform = #unix
ifTrue: [SubclassThatLeveragesUnix basicNew]
ifFalse: [CrappyPCSubclass basicNew]
请注意,我们在此使用basicNew
,而不是new
。如果您使用new
,则需要在这些子类中实现不同的覆盖,否则它将只是继承并重新发送AbstractClass>>>new
消息。
答案 1 :(得分:4)
......或者你可以这样做:
AbstractClass class>>#new
^ (self platform concreteClassFor: self) basicNew initialize.
这基本上是相同的想法,但没有ifs:)
答案 2 :(得分: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。请注意,我们有足够的信息,所以我们可以快捷第二个+调用,
示例显示的是,在第一次调用期间,动态消息解析在方法上找到(因此它定义为动态情况),然后通过交换参数和接收器,动态消息解析执行另一种情况,基于ARG。因此,最后您将获得使用原始调用的两个对象选择的方法。 现在关于你的问题:在Pharo类中,动态查找消息,这样你就可以使用双重调度实现实例创建方法而没有问题,但目标不明确。
MyClass class>>newWith: arg
arg newFromMyClass: aClass