I stopped reading as soon as I saw the shape class. This example (along with the proverbial animal) has done a lot of harm to OOP and programming. You need base classes (which are not always the right answer, but when they are) to be based on the abstract concept you need to model not something real that is easy to understand when someone isn't an expert in your domain.
Maybe give shape another try.
https://www.youtube.com/watch?v=zHiWqnTWsn4
1:00:00 - Open/closed principle and 1:13:52 - Liskov substitution principle.
Both are given in terms of Shape, but it's to paint the picture that things are more complicated than you thought, even with something that should have been as simple as shapes.