TITLE: is a circle an ellipse? [ This thread reappears about every nine months on the news groups. Robert Martin, author and editor of "C++ Report", usually makes the most sense, IMHO. -adc ] (Newsgroups: comp.lang.c++, 20 Feb 97) TIMMERMANS: mtimmerm@microstar.com (Matt Timmermans) > >... > >So I put it to you, OO language authors, that if one can't make circle > >a subclass of ellipse, then it is a deficiency of the language, not > >the programmer. MARTIN: rmartin@oma.com (Robert C. Martin) No, it is a deficiency in concept. There is no reason to expect that an elipse as specified in geometry must have the same relationships as an elipse specified in software. A geometrical elipse cannot be stretched. It does not have behavior. But a software elipse is an object that has behavior. It might be stretched, translated, rotated, scaled, etc. These behaviors are outside the domain of geometry. A circle; which sharing some of the same static definitions as an elipse, does not behave the way an elispe behaves. Some of the methods that pertain to an elipse (i.e. setFocusA, setFocusB) simply don't apply to circles at all. Thus, from an OO point of view, the behavioral interface of a circle is not compatible with the behavioral interface of an elipse. When two objects have compatible behavioral interfaces, we say that they conform to the ISA rule. Sometimes we use inheritance to implement the ISA rule. (Sometimes we dont). Since the behavioral interface of a circle is not compatible with the behavioral interface of an elipse, the two do not conform to the ISA rule. It is improper to state that an Circle object ISA Elipse object. Some folks take this to mean that OO violates the rules of geometry since geometrically a circle is an elipse. However, the ISA rule is very limited in its scope. It does not describe things that are equivalent. Rather, it describes things that have compatible behavioral interfaces. Therefore, it cannot be used to describe a geometrical 'is a' relationship. --- (Newsgroups: comp.lang.c++, 20 Feb 97) JOHN: john@peacesummit.com [snip] > The circle/elipse problem presents the kind of intelectual/acedemic > exercise that we all need to keep us sharp and lively. We can easily > talk about which is *correct* from a mathematical point of view, but > before I start designing my code, I want to ask what will these objects > be used for. Clearly, the first question we need to ask is "What object > am I modeling?" We then need to ask "What will it be used for?" MARTIN: The Circle/Elipse issue is just one example of a violation of the Liskov Substitution Principle (LSP). But there are many many others, and it is very important for OO designers to be aware of this principle and the consequences of violating it. In short, the LSP states that any function that uses a base class must be able to use all the derivatives of that base class without knowing, and without caring. Clearly this is not the case with Elipse. A function that uses an Elipse object and then stretches that elipse in the X direction will get very confused if it is passed a circle. It will not be expecting the elipse to change in the Y direction. This kind of nonsubtitutability is common in poorly designed systems. Folks who are unaccustomed to the LSP will create derived classes that violate the invariants of the base classes. Then users of the base classes will have problems with the derived classes. These problems invariably lead the programmer to put if statements in the functions that use the base classes. e.g. something like: "If this elipse is really a circle then...." This is insidious. Suddenly, this function that uses a base class will have to be changed every time a new derivative of that base class is created.