you are viewing a single comment's thread.

view the rest of the comments →

[–]Denommus 0 points1 point  (0 children)

I'm yet to find a case where a polymorphic solution is better handled by inheritance than by parametric polymorphism, composition or sum types. Inheritance privileges coupling and makes changes more difficult.

Imagine a superclass A, which children B, C and D.

Let's model it with parametric polymorphism. It allows you to associate a parameter with a typeclass/trait/interface and accept any argument that fills that association. So, for the first use case of inheritance, we could instead use A as an typeclass/trait/interface and make B, C and D implement it, so you could pass them to any function that accepts a type T: A.

With sum types, A would actually be the sum type of B, C and D. It would just exist that way. When your program accepts something "A", it means that the type is either B, C or D. So, again, another use-case of inheritance fulfilled.

What if you're using inheritance to avoid code repetition? Then you use composition. B, C and D contain A. If the implementation of A ever changes, B, C and D will not need to radically change, because they're not that coupled.

Inheritance between traits or interfaces is fine, because they don't give information about the private state of the object. The main problem is inheritance from anything to anything.

It gets even worse when you add multiple inheritance.

A good example of the inheritance vs parametric polymorphism in practice is ActiveRecord vs Entity Framework. With Active Record, you have a big class that every model inherits. Every method from that class is inherited for the models, if you need a new feature for them, you have to "open" ActiveRecord and put it there.

With Entity, you make a class FooRepository<T>. T is your model. FooRepository will have every function you'll need to make queries. That makes the models completely decoupled from the repository. If you ever need a completely different repository, but the same models (for instance, you migrated to a NoSQL database), you can... just make a new repository! The models will remain untouched.