Hacker News new | ask | show | jobs
by macintux 3457 days ago
Most eye-opening moment in my software engineering class was when the professor asked, of four core OO features (don't recall the precise list now), which was superfluous.

The answer, of course, was inheritance, and once the question was asked it wasn't hard to see how much better life could be without it. I've been on an anti-inheritance kick ever since.

Now I see how much better life can be without OO entirely, but that's a different discussion.

4 comments

I think that inheritance can have a place. It makes a lot of sense when writing //small variations// on an otherwise rich inner class. Small variations might include layering on a different input or output mechanism, or possibly handling 'extra' data that the object stores but previously did not modify.
You can achieve the same with composition or parametrisation. Both of which are the only tools in a functional language.
You can achieve the same in any Turing complete language.

However, composition and parametrization require up-front design and are usually only viable for large-ish variations.

As the parent said, inheritance handles the case of refinement, that is, programming by difference, which composition and parametrization handle with difficulty (if planned for) or not at all (if not planned for).

The bad rap inheritance gets is that it is often misused in places where composition or parametrization were appropriate. But that's just the old "it hurts when I poke myself in the eye with a sharp stick": don't do that.

http://www.metaobject.com/papers/Diplomarbeit.pdf

If you include interfaces you've essentially split inheritance into separate parts. Which isn't necessarily a bad idea.
What do you use to implement interfaces then?

Generic interfaces are the one single feature that made OO popular for GUI programming; what by its turn is the one application that made OO popular. And it's still the most powerful of the OO concepts (what is shame really).

Are you referring to the fact that in Java interfaces are basically pure virtual classes? That always felt like an implementation detail to me. For example, both Go and Rust have interfaces without inheritance.
I'm referring to a pattern on OO languages where you specify an interface using a superclass¹, with hooks that you can specialize on subclasses, reusing most of the code on the superclass and keeping the code around it generic.

Go interfaces have the part about keeping the code around it generic, but I don't think it gets the easy reuse of code by just writing the hooks. (But I can easily be wrong here - I'm not a proficient Go programmer.) In that, it looks very like Java's interfaces (the literal Interface thing).

1 - In Java you would not use a literal Interface for that, since you can't provide default code for the subclasses to extend.

Sometimes (hard to say without a specific example) the superclass can be represented as its own class and included in each subclass as composition. This has several advantages, including less code per class and therefore smaller interface surface area, more explicit interface / information hiding, and easier testability.
The most obvious examples would be the widget classes all GUI frameworks export. Java has some interesting classes for networking, like its AbstractHTTPServer, and Applet. Most OO languages have some variant of Thread or Runnable that is built this way too.
With just interfaces you can produce a variation of the pattern you describe by using an interface that specifies the hooks, having the concrete types implement the hook interface, and using a proxy that implements the shared behavior by consuming the hook interface.
Eh, inheritance is a subset of composition. One of the issues is that the subset is ambiguous and different languages create a different contract for it, but there's nothing theoretically wrong with inheritance.
That reminded me of Bob Martin on "object oriented C" - https://youtu.be/t86v3N4OshQ?t=1120