> Between duck-typing languages like python and javascript and the minefiled that is C++, I think Java and C# fit a pretty nice sweet-spot.
Imagine where we would be if an actually good way of doing type systems had been invented in the 1970s and there was a whole family of languages that followed that approach. Oh wait.
> Java absolutely has "just data", they're mostly used for DTOs and database Entities, with tools like lombok @Data and `records` being some nice mechanisms of implementing them.
The fact that you have to step outside the language with @Data rather proves the point. And while Java now has a "record" keyword, they're still reference types, with turning them into actual values being something that's supposedly coming Real Soon Now for 10+ years.
> Inheritance, when used for implementing is-a relationship, is a pretty powerful tool. If you're surprised by overriding, maybe instead of complaining about `Parent parent = new Child()` examples, try to see a `Writer writer = new PdfWriter()`. Are you still surprised that `writer.write(document)` generates a pdf?
Inheritance is a conflation of 3 useful features (interfaces, composition, and delegation) that's a lot less useful than the sum of its parts. Better languages separate these out properly. (And, credit where it's due, Java made a positive step in normalizing the separation of interfaces from the other parts of inheritance).
> There are absolutely horrible ways of designing code in Java, but that can be said about any language.
That's a cop-out. No language completely eliminates bad code, but there are better and worse languages.