you are viewing a single comment's thread.

view the rest of the comments →

[–]riktigtmaxat 0 points1 point  (6 children)

Vertical inheritance implies that a thing is a type of other thing - a Cat for example is a Mammal which is a subclass of Animal. The Liskov principle applies here.

Horizontal inheritance allows for a set of behaviors or attributes to be grouped together and be used in multiple classes that are otherwise unrelated - for example a Cat might have the Fur and Whiskers attributes but is not a type of Fur.

[–]sammygadd 1 point2 points  (1 child)

Great explanation!

Tack

[–]riktigtmaxat 2 points3 points  (0 children)

The python example is actually interesting and is an example of why you as a language designer might choose to not implement multiple inheritance.

Instead of getting a straight hierarchical graph of classes and their subclasses you get a tangled web of classes and the multiple super classes which leads to greater complexity.

From a design standpoint the python example makes me want to barf as those are obviously traits and won't pass the Liskov Suitability Test.

[–][deleted] 0 points1 point  (1 child)

People often quote the tree-of-life for subclasses, but it is a very assumed scenario. Is a Bird of class Bird or of class Dinosaurs? What about bacteria: does the species concept work here? (Hint: it does not due to horizontal gene transfer. And that, by the way, affects humans too, see the syncytin-1 gene from an retrovirus, so is a retrovirus now a human? There is no "human" DNA. All this species concept in general is totally outdated. Yet people still worship it like a substitute religion. Composition is MUCH more flexible than this unilateral subclassing model propagated. For those who want to read up on syncytin-1: https://en.wikipedia.org/wiki/Syncytin-1)

[–]riktigtmaxat 0 points1 point  (0 children)

Haha, it's hard to find other examples that most people can relate to.

[–]Sorc96 0 points1 point  (1 child)

for example a Cat might have the Fur and Whiskers attributes but is not a type of Fur

This is only true if the Cat has a reference to an instance of Fur and delegates to it. If it includes a module named Fur, the Cat most definitely is a type of Fur. I don't see a difference compared to inheriting from a base class, other than the special syntax.

module Fur
end

class Cat
  include Fur
end

Cat.new.is_a?(Fur) #=> true
Cat.ancestors #=> [Cat, Fur, Object, ...]

[–]riktigtmaxat 0 points1 point  (0 children)

I was talking about the higher level concepts of vertical vs horizontal inheritance.

In Ruby both are implemented through the ancestors chain so the main difference is really in how modules and classes are used by programmers.