Inheritance Benefits

<aside> 💡

In Go, even though it can use Anonymous Embedding to mimic inheritance, but it is not idiomatic. The Reusable Shared Logics should be a helper function or re-implement in concrete objects instead of a method in Abstract object.

Example:

Inheritance Issues

If the object we're inheriting is a concrete component (not an abstract base class), it could cause problems.

This principle holds true especially in Structural Patterns, where the goal is to wrap concrete objects**,** not to extend abstractions.

Diamond Problem

In TypeScript, when two superclasses have a common ancestor, method or property.

Class A -> method()
Class B extends A -> method()
Class C extends A -> method()
Class D extends B, C -> ??? (Which method() to use?)

e.g., If we use Inheritance in Facade pattern

In Java, it disallows multiple inheritance of classes.

In Go, the conflict of anonymous embedding multiple types, the compiler throws an ambiguity error. Anonymous Embedding

No Runtime Wrapping

The wrapping behaviour by Inheritance can not be done at runtime. Hard-coding all possible wrapping is dirty.

e.g., If we use Inheritance in Decorator pattern

Coupling

Even though the wrapping behaviour is not going to wrap multiple concrete objects or be at runtime. Wrapping behaviour via inheritance tightly is defying the SOLID’s Dependency Inversion Principle (DIP), which favor abstraction dependencies.

e.g., If we use Inheritance in Proxy and Adapter patterns

Even though we are not wrapping an object but making an abstract object for concrete objects, if there are no Reusable Shared Logics, the coupling is unnecessary.