Live data from Hacker News

Why general inheritance is flawed and how to finally fix it

minborgsjavapot.blogspot.com

1–10 of 104 posts

Re: Why general inheritance is flawed and how to finally fix it

#4
I (happily) write a lot of OOP code, "inheritance is bad, use composition" is such a trite and unhelpful dogma that gets in the way of any actual discussion about where inheritance is useful.

IMO, the case where inheritance makes the most sense is when you have a set of objects polymorphically answering some question, usually with a simple answer.

    class Subset
        class Whole 
which is used as such:

    subset = Subset::Whole.new
    puts subset.of(["a", "b", "c"]) # => ["a", "b", "c"]

    subset = Subset::Range.new(from: 0, to: 1)
    puts subset.of(["a", "b", "c"]) # => ["a"]
You can then pass around a Subset object anywhere (aka dependency injection) and push conditionals up the stack as far as possible.

Simply saying "inheritance is bad" gets nobody anywhere.

Re: Why general inheritance is flawed and how to finally fix it

#5
I think that composition is absolutely better than inheritance except for one thing: boilerplate. The issue is that boilerplate is kind of important.

You don't want to litter your code with "f150.ford.car.vehicle.object.move(50, 50)". You can and should re-implement "move" so that you only have to call "f150.move(50, 50)", but that still requires boilerplate, just in the "F150" class.

Often you have class containing all of the functionality of another class, except a bit more functionality. You can always use composition but this happens so often you're creating a lot of boilerplate.

You could develop some other "syntax sugar" to replace inheritance. Maybe Haskell's type-classes are better (although they also kind of use inheritance, since there are subclasses). But chances are you'll go back to something like inheritance, because it's very useful very often.

Re: Why general inheritance is flawed and how to finally fix it

#6

I think that composition is absolutely better than inheritance except for one thing: boilerplate. The issue is that boilerplate is kind of important. You don't want to litter your code with "f150.ford.car.vehicle.object.move(50, 50)". You can and should re-implement "move" so that you only have to call "f150.move(50, 50)", but that still requires boilerplate, just in the "F150" class. Often you have class containing…

Go solves this with problem with embedding. If a type is imbedded inside of a struct and has its own methods, those methods are implicitly available on the new struct.

Re: Why general inheritance is flawed and how to finally fix it

#7

I think that composition is absolutely better than inheritance except for one thing: boilerplate. The issue is that boilerplate is kind of important. You don't want to litter your code with "f150.ford.car.vehicle.object.move(50, 50)". You can and should re-implement "move" so that you only have to call "f150.move(50, 50)", but that still requires boilerplate, just in the "F150" class. Often you have class containing…

For the same reason, I'm not so absolutist about DRY. Having the most elegant codebase also often means the codebase that's hardest to work on, and it's often better to clean things up afterwards once you know how things will be structured.

Re: Why general inheritance is flawed and how to finally fix it

#8
post #7

I think that composition is absolutely better than inheritance except for one thing: boilerplate. The issue is that boilerplate is kind of important. You don't want to litter your code with "f150.ford.car.vehicle.object.move(50, 50)". You can and should re-implement "move" so that you only have to call "f150.move(50, 50)", but that still requires boilerplate, just in the "F150" class. Often you have class containing…

For the same reason, I'm not so absolutist about DRY. Having the most elegant codebase also often means the codebase that's hardest to work on, and it's often better to clean things up afterwards once you know how things will be structured.

See also: the wrong abstraction is worse than no abstraction at all.

https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction

Re: Why general inheritance is flawed and how to finally fix it

#9

I (happily) write a lot of OOP code, "inheritance is bad, use composition" is such a trite and unhelpful dogma that gets in the way of any actual discussion about where inheritance is useful. IMO, the case where inheritance makes the most sense is when you have a set of objects polymorphically answering some question, usually with a simple answer. class Subset class Whole which is used as such: subset = Subset::Whole…

In most languages Subset would be called a trait or interface, rather than general inheritance. You've picked an example with no fields or overriden methods, so it's impossible for it to demonstrate the shortcomings of inheritance.

Re: Why general inheritance is flawed and how to finally fix it

#10
post #3

Re: using composition In the past, it was feared that this would lead to reduced performance but this is simply not the case. Great to see the strong evidence here /s

It might be more productive if you were to outright disagree with the statement instead of simply noting a claim that isn't strongly substantiated. If you have experiences that demonstrate to you that this claim is weak I'm sure everyone else would be interested in them (I know I would be!).
Post reply on HN