> Liskov substitution is useless, you should not use inheritance but composition.
Liskov substitution is more about interface inheritance than implementation inheritance, really. LSP basically says that the implementer of an interface must obey the contract the interface specifies. As a real-world example, throwing UnsupportedOperationException in a method implementation is an LSP violation. Of course, this makes it vital to get the interfaces themselves right, carving the solution space at its joints.
Ok yes, it is about subtypes and interface is quite of an abstract base class. But if you have interface as in Java or C# and maybe 2 or 3 implementations without complicated type hierarchy under it, it is not an issue in practice to be not strict about contract, because you can spot deviation from it and fix it quick (ideally you also have integration tests to spot it for you).
I think the point is to forget about specific language features for a moment and think about interfaces the same way a mechanical or electrical engineer does -- as things to be glued together.
No, Liskov substitution is much more abstract level, if you go with physical interface definition it does not work at all. It is not about attaching things but about type hierarchy. Thing you describe does not account for Covariance and Contrvariance and then it also goes into generic types which also huge abstraction which does not fit in physical world.
Liskov substitution is more about interface inheritance than implementation inheritance, really. LSP basically says that the implementer of an interface must obey the contract the interface specifies. As a real-world example, throwing UnsupportedOperationException in a method implementation is an LSP violation. Of course, this makes it vital to get the interfaces themselves right, carving the solution space at its joints.