Live data from Hacker News

Why general inheritance is flawed and how to finally fix it

minborgsjavapot.blogspot.com

21–30 of 104 posts

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

#21

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…

I'd like to point out that the article isn't disagreeing with you. It's saying inheritance is a dangerous interface for other users of your code (across packages is their terminology). So, if you write a library, maybe don't design it around extending classes. This is a much milder stance than the title implies, and seems pretty reasonable to me.

Edit: Totally with you on boilerplate though. +1.

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

#22
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!).

"what may be asserted without evidence, may be dismissed without evidence"

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

#25
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

I mean, I'm not sure where this 'fear' even came from?

At its core, inheritence is a special case of composition anyways (looked at from the other perspective it's syntactic sugar over either static or dynamic delegation), so it can't really be "faster".

At any rate, there's no abstraction so powerful it can prevent a programmer from making it slow.

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

#26

Earlier quoted context omitted.

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.

What is the practical difference between inheritance, and a trait or interface with a default implementation? It seems like both risk the addAll() bug.

Multiple inheritance is basically strictly more powerful than either traits or interfaces with default implementations.

I don't think traits or interfaces with default implementations prevent the bug, as I can imagine a Rust implementation that would do something similar.

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

#27
The term "general inheritance" was not familiar to me as "inheritance across package structures". However, my OOP design intuition feels pretty good about that idea.

This quickly devolves into the inheritance vs. composition argument which isn't where I thought the Author wanted to go (but then sort of ended up going there). I agree with other commenters that it's an overstated idea. Inheritance is ridiculously useful in the right design structure, as is Composition. They both have a place. (Incidentally, bad Inheritance design usually looks very ugly very fast - bad Composition is often less glaring).

I find that years of designing in OOP has led me to build designs that have a goal of preventing me from making future mistakes and correctly consider implications of my code.

I find that my most immediate designs tend me towards Abstract Classes and Interfaces. While I usually get credit for "programming to the Interface" for this, that's not what usually led me there.

I like abstract methods. They (i.e. the compiler will) FORCE me to think about something if I ever decide to create another subclass of the Abstract class. The Author points out the "forget to call super" bug which is particularly nefarious and I avoid it at all costs. I can do that by providing a final concrete method which calls the abstract method. Let the subclasses implement that and never worry about super.

Anyway - governing inheritance across package hierarchies seems like a reasonable guideline. As for Inheritance vs. Composition, I don't favor either. When designing a class structure, I just make my best guess (as we'd all do) and find the structure quickly evolves on it's own. Usually, this ends up in a blend of shallow Inheritance trees with logical composition. There's always multiple Class Structures that will work - my goal is to find a reasonable one of those.

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

#28
I feel the flaw is in building ontologies. Satic ones, at that.

There is great value in reducing type errors at runtime. Is hilariously ironic that one of the main tools we reach for seems intent on just moving them to design time.

Notably, not compile time. Design. Most failures from mistakes in ontology stall the problem out before release.

(Obviously, ymmv.)

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

#29
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

I mean, I'm not sure where this 'fear' even came from? At its core, inheritence is a special case of composition anyways (looked at from the other perspective it's syntactic sugar over either static or dynamic delegation), so it can't really be "faster". At any rate, there's no abstraction so powerful it can prevent a programmer from making it slow.

This is true for languages where most objects are not garbage-collected. In Java (modern days) this would add a level of indirection.

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

#30

Earlier quoted context omitted.

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.

What is the practical difference between inheritance, and a trait or interface with a default implementation? It seems like both risk the addAll() bug.

Not all languages allow for an interface to have a default implementation though. Delphi for example does not.

This leads the programmer towards composition and delegation.

To aid with this, Delphi even has some sugar for delegation[1].

[1]: https://docwiki.embarcadero.com/RADStudio/Alexandria/en/Usin...

Post reply on HN