There are others that are also _very_ interesting (but also pre 90s). SELF fe, was object oriented, but did not have inheritance. It used prototypes. In essence, you would create something of the same "type" by cloning the prototype.
Anyway, subtyping and inheritance are similar, but not identical, concepts. Also, some languages provide traits iso protocols (and maybe even both ?). Some languages provide functors. The goal is always the same: abstract commonalities. Let's just keep it at: "it's complicated" ;)
I think it's better to study the design mistakes of programming languages in a historic context. For example: C++ offers multiple inheritance. This caused the diamond problem. Java tried to fix this via interfaces. This fixed the problem, but was also a mistake as interfaces cannot provide behaviours. So Multiple inheritance is not an issue if only 1 of the parties provides state; all others can provide signatures but also behaviours.