From: Robert Klemme Date: 2011-04-07T23:28:47+09:00 Subject: Re: Hash Surprises with Fixnum, #hash, and #eql? On Thu, Apr 7, 2011 at 4:02 PM, Phillip Gawlowski wrote: > On Thu, Apr 7, 2011 at 3:43 PM, Robert Klemme > wrote: >> If you see inheritance as "is a" relationship then inheritance would >> be Rational < Real < Complex but not the other way round.  Otherwise >> you cannot use a subclass instance everywhere you were using a >> superclass instance. > > Though, does the "is a" relationship hold up? I think it's more of a > "kind of" relationship, where subsequent classes are defined in ever > more detail (so, you'd inherit Floats from Integers, and Complex from > Float). 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. Of course, all those considerations are far less important in a nicely duck typed language like Ruby compared to a statically typed language. Assuming you would do the same in Java you would have to declare the exception (if you use checked exceptions) on Real class but state at the same time that this class would never throw it. Even worse, all code using Real would have to deal with this exception by either catching or propagating it. Not nice. 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. > Of course, the clean world of maths doesn't map 1:1 to computational > systems, so I see the value in both approaches. That's true. I remember debates about the very question how to model inheritance hierarchies for numeric types. Unfortunately I can't produce a reference right now. Maybe someone else can. > But, frankly, given the differences and additional properties of > complex numbers, I'd derive it from Numeric as well, simply to limit > the side effects the other numeric classes introduce (Floats and their > CPU-internal representation give me nightmares :P). :-) Also, with Ruby's concept of coercion inheritance between numeric types is probably less of an issue. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/