Source of LiskovSubstitutionPrincipleViolated.java


  1: //LiskovSubstitutionPrincipleViolated.java
  2: //Illustrates a violation of Liskov's Substitution Principle, for
  3: //which see the Wikipedia description quoted at the end of this
  4: //file. Bottom line ... be careful when you extend a class that
  5: //the derived class really does satisfy the "is a" relationship.

  7: class Rectangle
  8: {
  9:     protected int width;
 10:     protected int height;

 12:     public void setWidth(int width)
 13:     {
 14:         this.width = width;
 15:     }

 17:     public void setHeight(int height)
 18:     {
 19:         this.height = height;
 20:     }

 22:     public int getWidth()
 23:     {
 24:         return width;
 25:     }

 27:     public int getHeight()
 28:     {
 29:         return height;
 30:     }

 32:     public int getArea()
 33:     {
 34:         return width * height;
 35:     }
 36: }

 38: class Square extends Rectangle
 39: {
 40:     public void setWidth(int width)
 41:     {
 42:         this.width = width;
 43:         this.height = width;
 44:     }

 46:     public void setHeight(int height)
 47:     {
 48:         this.width = height;
 49:         this.height = height;
 50:     }
 51: }

 53: class LiskovSubstitutionPrincipleViolated
 54: {
 55:     private static Rectangle getNewRectangle()
 56:     {
 57:         return new Square();
 58:     }

 60:     public static void main(String args[])
 61:     {
 62:         Rectangle r = LiskovSubstitutionPrincipleViolated.getNewRectangle();

 64:         r.setWidth(5);
 65:         r.setHeight(10);
 66:         //User knows that r is a rectangle.
 67:         //So he assumes he can set width and height as for the base class.

 69:         System.out.println(r.getArea());
 70:         //But now he's surprised to see that the area is 100 instead of 50.
 71:     }
 72: }

 74: /*
 75:     In Java, S is a subtype of T if S extends or implements T.

 77:     The (Liskov) Substitution Principle
 78:     A variable of a given type may be assigned a value of any subtype, and a
 79:     method with a parameter of a given type may be invoked with an argument
 80:     of any subtype of that type.

 82:     Further explanation ...
 83:     Substitutability is a principle in object-oriented programming that states
 84:     that, in a computer program, if S is a subtype of T, then objects of type
 85:     T may be replaced with objects of type S (i.e., an object of the type T
 86:     may be substituted with its subtype object of the type S) without altering
 87:     any of the desirable properties of that program (correctness, task
 88:     performed, etc.). More formally, the Liskov substitution principle (LSP)
 89:     is a particular definition of a subtyping relation, called (strong)
 90:     behavioral subtyping, that was initially introduced by Barbara Liskov in
 91:     a 1987 conference keynote address entitled Data Abstraction and Hierarchy.
 92:     It is a semantic rather than merely a syntactic relation because it
 93:     intends to guarantee semantic interoperability of types in a hierarchy,
 94:     object types in particular. Barbara Liskov and Jeannette Wing formulated
 95:     the principle succinctly in a 1994 paper as follows:

 97:     Subtype Requirement:
 98:     Let p(x) be a property provable about objects x of type T. Then p(y) should
 99:     be true for objects y of type S where S is a subtype of T.
100: */