我是Pharo的新手,我很难掌握一些概念,特别是subclassResponsibilty
。
我有以下对象树:
AbstractDictionary
--TreeBasedDictionary (not abstract)
--AbstractArrayDictionary
----SimpleDictionary (not abstract)
----FastDictionary (not abstract)
所有3个实现操作at:put:
和at:
(以及更多)。我今天从课堂上了解到,我可以通过以下实施方式将at:put:
提升到AbstractDictionary
:
at: thisKey put: thisValue
"insert new key / value pair"
^self
at: thisKey
put: thisValue
duplicate: [self error:'duplicate key']
然后我在at:put:duplicate:
中实现了一个metod TreeBasedDictionary and AbstractArrayDictionary
(因为后者的子类的实现是相同的)。然后,当我在一个对象上调用at:put:
时,它不会在TreeBasedDictionary , SimpleDictionary or FastDictionary
的实例中找到它,但在查找树时,它会在超类(AbstractDictionary)中找到此方法。然后,这将使用at:put:duplicate:
调用self。这个方法由上面提到的3个类实现,然后指向进行初始调用的类实例的self被发送到执行at:put:duplicate:
的消息。
现在,AbstractArrayDictionary,SimpleDictionary and FastDictionary
都有一个名为size
的方法。继承树底部的两个类都实现了这个方法。 AbstractArrayDictionary
实现此方法如下
size
"dictionary size"
self subclassResponsibility
假设我为TreeBasedDictionary
实现了此方法,我想我应该在AbstractDictionary
类中实现size方法,如上所示。
我的问题:为什么我需要这样做,而不是这样:
size
"dictionary size"
^self size
如果是这样,我会从AbstractArrayDictionary
删除该方法吗?为什么?
答案 0 :(得分:10)
好的,看。
首先,如果您使用
size
^ self size
你将最终进入无限递归。您询问size
对象,size
方法询问对象本身的size
,依此类推。
现在一般来说你应该知道什么。
self subclassResponsibility
编写方法。对象应该响应他们可以理解的消息。 AbstractDictionary 可以将元素放入其中吗?不,那就没有办法了。at:put:duplicate:
,但功能取决于实现(也就是子类)。at:put:duplicate:
,然后在执行期间,他会被温和地提醒,这是一个子类责任,该方法应该实施。否则他将收到错误“MagicBagDictionary无法理解的消息”。再次关注size
方法:如果您知道某个地方可以获得大小 - 请执行此操作。例如,如果 AbstractDictionary 具有实例变量container
,它将包含所有元素并且应该能够告诉它们的大小 - 您可以实现
size
^ container size
AbstractDictionary 中的。但如果您不知道该元素将被存储以及如何计算它们的大小,您应该使用:
size
"dictionary size"
self subclassResponsibility
AbstractDictionary 这样说:
是的,你可以得到我的体型,但我不知道如何计算它因为我不完整。但是我的子类应该知道,所以不要犹豫。