The problem tends to be that "is-a" is conveniently short but it confounds several different types of inheritance.
Inheritance in most OO languages really means "api is a superset of, and implementation is a specialization (and possibly superset) of" while in natural language "is-a" implies a relationship where some facets might be expanded, while others may be more restricted.
This is really partially a weakness in expressiveness of our languages, partially a problem of our frequent insistence on mutability. Often the problem goes away with immutability: If your "square" is immutable and inheriting from a "rectangle" class that allows setting width and height to different values isn't a problem, because the result would be a new object and that result can be a rectangle.
But sometimes we also genuinely would be best served by inheriting implementation and public API separately without having to create cumbersome facades etc. - it's just that making an API of a subclass a subset of the API of the superclass violates a lot expectations people tend to have about OO systems, and so few systems outside of prototype based ones seem to allow it without resorting to ugliness like overriding methods to make them throw exceptions etc.
Inheritance in most OO languages really means "api is a superset of, and implementation is a specialization (and possibly superset) of" while in natural language "is-a" implies a relationship where some facets might be expanded, while others may be more restricted.
This is really partially a weakness in expressiveness of our languages, partially a problem of our frequent insistence on mutability. Often the problem goes away with immutability: If your "square" is immutable and inheriting from a "rectangle" class that allows setting width and height to different values isn't a problem, because the result would be a new object and that result can be a rectangle.
But sometimes we also genuinely would be best served by inheriting implementation and public API separately without having to create cumbersome facades etc. - it's just that making an API of a subclass a subset of the API of the superclass violates a lot expectations people tend to have about OO systems, and so few systems outside of prototype based ones seem to allow it without resorting to ugliness like overriding methods to make them throw exceptions etc.