Inheritance

In this post we will look at how different types of inheritance can be translated to OWL. We consider the case where Person is specialized by Employee and Client (Fig. 1). In a UML class diagram if inheritance is not annotated the default annotation {incomplete, disjoint} is assumed. incomplete means there are instances of Person which are neither of type Employee nor Client. disjoint means there is no instance of Person that is both of type Employee and of type Client. The set representation is given in Fig. 2 and the OWL translation in Fig. 3.

InheritanceDefault

Fig. 1

InheritanceDefaultSet

Fig. 2

InheritanceDefaultOWL

Fig. 3

The annotation {complete, disjoint} means every instance of Person is either a instance of Employee or an instance of Client(Fig. 4). The corresponding Venn diagram is  given in Fig. 5 and the OWL translation in Fig. 6.

InheritanceCompleteDisjoint

Fig. 4

InheritanceCompleteDisjointSet

Fig. 5

InheritanceCompleteDisjointOWL

Fig. 6

When overlapping is used rather than disjoint it means an instance of Person may be both of type Employee and of type Client.  Fig. 7 – 9 provides a UML class diagram, Venn diagram and OWL translation as example for the annotation {incomplete, overlapping}. Fig. 10 – 12 provides a UML class diagram, Venn diagram and OWL translation as example for the annotation {complete, overlapping}.

InheritanceIncompleteOverlapping

Fig. 7

InheritanceIncompleteOverlappingSet

Fig. 8

InheritanceIncompleteOverlappingOWL

Fig. 9

InheritanceCompleteOverlapping

Fig. 10

InheritanceCompleteOverlappingSet

Fig. 11

InheritanceCompleteOverlappingOWL

Fig. 12

The Rectangle/Square Controversy

A software design problem that has often been discussed in the literature is whether a square should inherit from a rectangle or whether a rectangle should inherit from a square? Two opposing arguments are made by Meyer [1] and Martin, et.al. [2], both of which seem to have some merit. How is a software developer to decide which is the correct design? In this post I will discuss why I believe both approaches are wrong and I will provide the solution I prefer.

Meyer [1] proposes the design where square inherits from rectangle with square imposing the invariant that the width must equal the height. The conceptual design is shown in Figure 1. This design makes sense since a square “is-a” rectangle. Remember, that “is-a” is the litmus test for inheritance [3]. To state this more precisely: inheritance defines a subset relation between a child and a parent class. Thus, the Square class represents the set of squares which is a subset of the set of rectangles which is represented by the Rectangle class. This is shown in Figure 2. For a detailed discussion on the mathematical semantics of inheritance, see Meyer [1]. The implementation is shown in Figure 3.

Figure 1: Square extends Rectangle

Figure 1: Square extends Rectangle

Figure 2

Figure 2: The set of squares is a subset of the set of rectangles

Figure 3

Figure 3: The implementation of a Square extending a Rectangle

Martin’s criticism against the design of Figure 1 is that it violates the Liskov substitution principle, which states that subtypes must be substitutable for their base types [2]. Clients of instances of the Square class cannot set the width and height of a square as if they are using a rectangle. In particular they need to ascertain that the width and height of instances of square are equal. The main problem is that a square does not require both a width and a height and it therefore needs to ignore either of the attributes.

An alternative design that Martin discusses is where the setWidth (respectively setHeight) method is changed to set the height equal to the width (respectively to set the width equal to the height). However, the problem is when setWidth (respectively setHeight) is called it will overwrite the value of the height (respectively width) (see Figure 4). Hence, a client that first sets the width to 5 and then the height to 3 will expect the perimeter to be 16, but instead it will be 12. This again violates the Liskov substitution principle.

Figure 4

Figure 4: Forcing the width and height to be equal

The solution that Martin [2] proposes is that the Rectangle class must inherit from the Square class (see Figure 5). The objection that Meyer has against this design is that it violates the “is-a” relation in that a rectangle is not a square. Now you may reason that a rectangle is indeed a square when its width and height are equal, but the crucial point is that a rectangle is not always a square. Remember, inheritance enforces a subset relation between a child and a parent. That is, all instances of the child are necessarily instances of the parent, but not all instances of the parent are necessarily instances of the child.

The flaw in the solution that Martin proposes is that he uses inheritance for the sole purpose of reuse without there being an “is-a” relation. Meyer calls this “convenience inheritance” which should be avoided.

Figure 5

Figure 5: Rectangle extends Square

From a conceptual perspective a way around these objections is to introduce a class (i.e. Quadrilateral) from which both the Rectangle and Square classes can inherit. The related UML class diagram is shown in Figure 6. The {incomplete, overlapping} annotation indicates that other quadrilaterals may exist and that rectangles may occasionally be squares (when width=height).

Figure 6

Figure 6: Conceptual solution for Square and Rectangle problem

The implementation of this conceptual solution can be done where Quadrilateral is either an interface or an abstract class. Figure 7 shows the implementation where Quadrilateral is defined as an interface.

Figure 7

Figure 7: A correct implementation for the Square and Rectangle classes

Naturally I am not the first to point this solution out. [5] gives a general discussion of the problem and [4] provides a solution similar to mine.

Bibliography

[1] B. Meyer, Object-oriented software construction, Prentice Hall, 1997.

[2] R. Martin and M. Micah, Agile principles, patterns, and practices in C#, Prentice Hall, 2006.

[3] G. Booch, R. A. Maksimchuk, M. W. Engel, B. J. Young, J. Conallen and K. A. Houston, Object-oriented analysis and design with applications, Addison-Wesley Professional, 2007.

[4] R. Carr, “Is a Square a Rectangle?,” [Online]. Available: http://www.blackwasp.co.uk/SquareRectangle.aspx.

[5] H. Makabee, “When a square is not a rectangle,” [Online]. Available: http://effectivesoftwaredesign.com/2010/09/20/when-a-square-is-not-a-rectangle/.