The SOLID principles are all you need to know. [0] Then realize through them that inheritance as generally taught is actually a bad idea and use interfaces instead. Then realize that interfaces are just a weaker version of type classes and reach enlightenment.
I had this thought recently that inheritance was a bad solution to languages not supporting containers natively. And or a lame attempt at code reuse. (A root class is an API/Service with no versioning)
Yes, as in Haskell type classes. Or Rust traits. Basically, anything that acts like an interface (defines a contract) but allows external definition. So you're not stuck wrapping your Integer in a ShowableInteger just to have an Integer that implements the Show interface.