I'm new to Pharo and I'm having trouble grasping some concepts, specifically subclassResponsibilty
.
I have the following objecttree:
AbstractDictionary
--TreeBasedDictionary (not abstract)
--AbstractArrayDictionary
----SimpleDictionary (not abstract)
----FastDictionary (not abstract)
All 3 implement the operations at:put:
and at:
(and more). I understood from class today that I can pull up at:put:
to the AbstractDictionary
with the following implementation:
at: thisKey put: thisValue
"insert new key / value pair"
^self
at: thisKey
put: thisValue
duplicate: [self error:'duplicate key']
Then I implemented a metod at:put:duplicate:
in TreeBasedDictionary and AbstractArrayDictionary
(because the implementation is the same for the latter's subclasses). Then, when I call at:put:
on an object it won't find it in the instance of either TreeBasedDictionary , SimpleDictionary or FastDictionary
but when looking up the tree it finds this method in the superclass (AbstractDictionary). This will then call self with at:put:duplicate:
. This method is implemented by the 3 afore mentioned classes, and then the self which is pointing to the instance of the class that made the initial call is sent the message to execute at:put:duplicate:
.
Now, AbstractArrayDictionary,SimpleDictionary and FastDictionary
all have a method named size
. Both classes at the bottom of the inheritence tree implement this method. AbstractArrayDictionary
implements this method as follows
size
"dictionary size"
self subclassResponsibility
Suppose I implemented this method for my TreeBasedDictionary
, I suppose I should implement the size method in my AbstractDictionary
class as shown above.
My questions: Why do I need to do it like that, and not like this:
size
"dictionary size"
^self size
And if so, do I remove the method from AbstractArrayDictionary
and why?
Ok, look.
First of all if you use
size
^ self size
you'll end up in the infinite recursion. You ask size
of object and the size
method asks size
of the object itself and so on.
Now in general about what you should know.
self subclassResponsibility
at all. Objects should respond to messages that they can understand. Can AbstractDictionary put elements in it? No. Then there can be no method.at:put:duplicate:
, but the functionality depends on the implementation (aka subclass).at:put:duplicate:
, then during execution he will be gently reminded that this is a subclass responsibility and the method should be implemented. Otherwise he will get an error "message not understood by MagicBagDictionary".Concerning the size
method again: if you know at some point where you can get the size - do it. For example if AbstractDictionary has instance variable container
that will hold all the element and should be able to tell the size of them - you can implement
size
^ container size
in the AbstractDictionary. But if you have no idea ho the element will be stored and how to calculate their size at that point, you should use:
size
"dictionary size"
self subclassResponsibility
This way AbstractDictionary is saying:
yes, you can get my size, but I have no idea how to calculate it because I'm not complete. But my subclasses should know that, so don't hesitate to ask.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With