Hacker News new | past | comments | ask | show | jobs | submit login

There is nothing wrong with inheritance. But sure, there is usually something wrong with deep inheritance or using it, where better solutions exist.



No, there's a lot wrong with inheritance. It leads to all sorts of issues and while theoretically one can keep the tree 1 level deep, in practice it's too tempting to expand the hierarchy.

This is one of Java's big issues. The other is reference equality as a default, pretty horrible. Records help but records are also limited in when they can be used.


"in practice it's too tempting to expand the hierarchy."

Not anymore, if you got stuck, by doing that once too often. But 2-3 levels can be allright as well. It depends, what you are doing amd with whom.


> No, there's a lot wrong with inheritance.

No, there is a lot wrong with bad code. No need to blame the language or any programming concept.

Note that I say that for all programming languages, not just Java.


That's a difference between a dangerously unsafe tool and a good tool. By unsafe I mean providing enough of footguns to shoot yourself in the foot. Java has a community of people that indulge in teaching about inheritance as the first thing after classes in their "OOP" lessons. This ingrains the habit in beginners.


> By unsafe I mean providing enough of footguns to shoot yourself in the foot.

Just to play on the comparison: would you say that a gun is a "dangerously unsafe tool"? I would tend to think that guns have been very well optimized over time, and I don't know of a gun design that prevents me from shooting myself in the foot. Actually that would be a limitation of the gun.

But we all agree that people who use guns need to learn how to use them properly. Why doesn't this apply to programming languages? How did we as an industry end up in a place where it's considered the norm that developers don't really know what they are doing and need some kind of child safety in order to not hurt themselves?


Yes, guns are dangerously unsafe, they're designed to cause harm. It's hard to reconcile that goal with the need for safety. That said, guns do have safeties - guarded trigger, safety switch, drop safety, etc. [1].

The general principle is to design in as much safety as possible without compromising the intended purpose of the tool too much. The degree to which this is possible varies. Inherently complex and/or dangerous tools like guns, cars and aeroplanes require significant training before safe operation is possible. Most tools however can be made perfectly safe to use for anyone without any special training. Like plugs and outlets [2].

Programming languages are no different. The history of PL design is defined by the ever increasing restrictions placed on what languages let programmers do in the pursuit of safety & correctness.

But really, we humans, especially programmers, have no clue what we're doing and need all the help we can get.

[1]: https://en.wikipedia.org/wiki/Safety_(firearms)

[2]: https://youtu.be/139Q61ty4C0?t=42, https://youtu.be/139Q61ty4C0?t=105, https://youtu.be/139Q61ty4C0?t=205


It seems you conflate the tool and the education about the tool?

Why is Java itself bad, because some people (maybe) teach it wrong?

Also inheritance as a first lesson with OOP is not bad either, if the follow up is sound. But as far as I know, the concept composition > inheritance was already taught 15 years ago.


If we look at other modern programming languages, some don't even have inheritance. Lets take Rust for example. The language from the get go avoids the trap of deep inheritance hierarchies, by ... not having classes and inheritance! Instead it has structs and traits you can implement for the structs. Behavior separated from structure. They learned from the mistakes or design flaws of the past. Sure, Rust is not perfect, but this aspect about it I really appreciate. I am sure though, that someone somewhere will implement something resembling inheritance and create footguns anew.

Lets compare with Java. Java has forced everyone for decades to shoehorn everything into classes (sometimes an enum, sometimes an abstract class, whatever). Last time I checked it was still impossible to simply open a file, put a function (!) inside and be done. No, Java forces you to wrap that into a class or similar construct, as if a function in itself was not enough and not self-sufficient. There is a whole mindset behind this, that seems to come from an ideological "everything must be a class, because then I can instantiate and then I haz objects and can call methods". Other languages don't need classes to have objects.

Decades fast-forward. Java learns, that lambda expressions are a nice idea. Java will offer structs. Java learns, that lightweight processes are very neat to have. And despite all that, the old footguns still remain and could only be undone at significant cost, because of backward compatibility. This is where programming language design sins really rear their head. PHP suffers from the same problem. Horrible standard library, but cannot be fixed, unless you break backward compatibility.

On one hand you can state, that it is all on the programming, who is "holding it wrong" or needs more education. On the other hand, the programmer can choose a better designed tool, that doesn't cut their fingers every time they try to use it. Just because it is possible to do a good job with Java, that does not mean, that Java is a good tool for the job. It means you can only let the most experienced people work with the tool, instead of what we have now, every Billy knowing Java, writing classes and getting a kick out of inheriting from a super class.

Good teaching will avoid weighing things one should avoid disproportional. There is no good reason to teach inheritance early on. It should be a thing taught on the side, something one quickly glances at and says: "Yeah, that also exists, but lets not get into that much, as we will not need it much ..."

But in Java you probably can't avoid it for long, because you will want to make use of some library sooner or later and library authors might force you to make some class inheriting from their library's class, define a behavior and pass that in. But often that is not enough ... No no no, you need to pass in a factory for classes, that implement an interface, and their methods will implement the actual thing. I have seen this recently for logic of checking, whether a password is valid/acceptable. Why the heck do I need to implement a factory for that, when the actual task is simplest logic, checking whether the password has all required kinds of characters in it?

Usually this is completely overblown, because you want to pass in some behavior, that could be expressed as a simple function. I shouldn't need to create some brimborium. All I should be required to do should be to implement the logic in a function and pass that as an argument to the library.

The existing ecosystem forces its "OOP" on you. If you are not willing to throw out decades of ecosystem, which actually is the main advantage of the JVM, then you will need to deal with the cruft that has been created before.


Ok, you don't have to convince me that Java has many problems, as I intentionally avoided Java for some of those reasons for the last 15 years. But thanks for reminding me of some of them ..

But the concept of inheritance I like. And I use it succesful allmost daily. And like I said, I am aware of how you can use it in the wrong way. And my code surely is not perfect either, but the flaws I have, do not come from inheritance. Those parts are actually very clear, solid and stable. And still flexible.

And Rust is trendy I know. I have never used so far, so it was news to me, that they don't even have inheritance, but to convince me, that Rust has the superior concept, I would like to see it to be used as widely as inheritance languages first.


[..] a programming language designer should be responsible for the mistakes that are made by the programmers using the language.

It's very easy to persuade the customers of your language that everything that goes wrong is their fault and not yours. I rejected that...

- Tony Hoare


I feel like it often goes in the other extreme: "if a 2 years old cannot use it, it's too hard".

I am fine with requiring that professionals know their tools, even if I'm well aware that this is not the norm.


You don't like code reuse?


Love it, and love using plain ol' functions for it


Inheritance is not necessary for code reuse.

All you really need for that is named procedures. A way to combine modules and different files certainly helps too.

Type hierarchies can even hinder code reuse, because you can’t just pick the stuff you actually need.


That question seems blatantly disingenuous.


Composition > inheritance.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: