From: Phillip Gawlowski Date: 2011-04-07T23:49:35+09:00 Subject: Re: Hash Surprises with Fixnum, #hash, and #eql? On Thu, Apr 7, 2011 at 4:28 PM, Robert Klemme wrote: > > Well, even with technical inheritance ("kind of") sub often add state > (i.e. member variables) but do only restrict valid values of > superclass state if at all.  The cannot do otherwise because then > superclass methods may break.  Silly example: superclass holds an > index which must be >= 0.  All superclass methods use that index for > some kind of lookup.  Assuming a sub class would suddenly set that > value to -13 the superclass contract would be violated.  Now, if you > let Complex inherit from Real (trying to avoid "irrational" :-)) you > would add another field for imaginary part.  So far so good, but > method to_f would sometimes throw an exception in Complex which it > would never do in Real.  So suddenly Complex breaks Real's contract. But that's a failure of implementation, isn't it? If I were to implement my own class Complex, I'd have to deal with the edge-cases that my sub-class has and can produce. Thus, I either undefine #to_f, or redefine it so that it throws an Exception. the value of inheritance is, after all, generalization, so that I don't have to reimplement the wheel all the time, instead making the wheel bigger or smaller, as the implementation requires. That conversely also means that that more specialized sub-classes derived from a generic-er super-class, *has* to implement an interface that works, and works consistently. To stay with Complex as an example: #to_f would require an additional argument to work properly: Either convert the real, or the imaginary part into a Float, and so would anything derived from Complex, whatever that may be, if it has the same properties. > That's why I prefer to look at inheritance as "is a" relationship: > after all OO is about better abstraction capabilities and to be able > to hide implementation details behind a clearly defined clean > interface.  If you let yourself get dragged too much into technical > issues chances are that the design comes out awful.  Only languages > which allow to inherit without publishing all features of the > inherited class (private inheritance e.g. in Eiffel) do not > necessarily suffer from these issues.  But then, inheritance is just > an implementation detail in such cases. But isn't it always? Regarding technical issues: Design is a bit of an art; knowing when to stop abstracting is important. ;) -- Phillip Gawlowski Though the folk I have met, (Ah, how soon!) they forget When I've moved on to some other place, There may be one or two, When I've played and passed through, Who'll remember my song or my face.