Rust removed inheritance only for the Rust ecosystem to generate some kind of half-inheritance system by sticking macros on everything. For every `extends Serializable`, Rust has a `#[derive(Serializable)]`. Superclasses are replaced by gluing the same combinations of traits together in what would otherwise be subclasses, with generic type guards.
The problems with bad design don't go away, they're just hidden out of plain view by taking away the keywords. Rust's solution is more powerful, but also leads to more unreadably dense code.
One clear example of this is UI libraries. Most UI libraries have some kind of inheritance structure in OO languages, but Rust doesn't have that capability. The end result is that you often end up with library-specific macros, a billion `derive`s, or some other form of code generation to copy/paste common implementations. Alternatively, Rust code just reuses C(++) code that needs some horrific unsafe{} pointer glue to force an inheritance shaped block down a trait shaped hole.
Java serialization is implemented with reflection, not inheritance. `extends Serializable` is just a marker which tells the serializer it's okay to serialize a class. Go serializes with reflection too, and there's no inheritance at all in that language.
> Rust's solution is more powerful, but also leads to more unreadably dense code.
Instead of reflection, Rust does serialization with code generation. Java does this too sometimes in libraries like Lombok. The generated code is probably quite dense, but I expect the Java standard library reflection-based serialization code is also quite dense. In both cases, you don't have to read it. `extends Serializable` and `#[derive(Serializable)]` are both equally short. And the generated code for protobuf serialization (which I have read) is pretty readable.
But classes are a really crap way to share code, since you get the is-a relationship rather than the has-a relationship which is almost always what you want to express. Rust traits and derive macros are a much better abstraction for everything I've ever done when contrasted with classes.
The problems with bad design don't go away, they're just hidden out of plain view by taking away the keywords. Rust's solution is more powerful, but also leads to more unreadably dense code.
One clear example of this is UI libraries. Most UI libraries have some kind of inheritance structure in OO languages, but Rust doesn't have that capability. The end result is that you often end up with library-specific macros, a billion `derive`s, or some other form of code generation to copy/paste common implementations. Alternatively, Rust code just reuses C(++) code that needs some horrific unsafe{} pointer glue to force an inheritance shaped block down a trait shaped hole.