class LiskovSubstitutionPrinciple
1: //LiskovSubstitutionPrinciple.java
2: //Illustrates Liskov's Substitution Principle.
4: import java.util.ArrayList;
5: import java.util.List;
7: class LiskovSubstitutionPrinciple
8: {
9: public static void main(String args[])
10: {
11: //The ArrayList class implements the List interface.
12: //So ArrayList<Number> is a subtype of List<Number>.
13: List<Number> numbers = new ArrayList<Number>();
15: //Auto-boxing converts the primitive integer and double to the
16: //corresponding wrapper objects, since both the Integer and the
17: //Double "wrapper classes" are subtypes of the Number class.
18: numbers.add(2016);
19: numbers.add(3.14);
21: System.out.println(numbers.get(0) + " " + numbers.get(1));
23: /*
24: But ... and this is counterintuitive ... it's illegal to do this
26: List<Number> moreNumbers = new ArrayList<Integer>();
28: because get and "incompatible types" error, because the
29: Substitution Principle does not work with generic types.
30: For suppose the above line did compile. Then later on
31: we might try to add a double to a List of Number that
32: was actually "only" an ArrayList of Integer.
33: */
35: }
37: /*
38: It's also illegal to pass a collection of a subtype to a method which
39: has a parameter of the supertype, as the following code illustrates:
40: class Animal { }
41: class Dog extends Animal { }
42: public void addAnimal(List<Animal> animals) { }
43: public void test()
44: {
45: List<Dog> dogs = new ArrayList<Dog>();
46: addAnimal(dogs); //Causes compile-time error!
47: }
48: */
49: }
50: /* Output:
51: 2016 3.14
52: */
54: /*
55: In Java, S is a subtype of T if S extends or implements T.
57: The (Liskov) Substitution Principle
58: A variable of a given type may be assigned a value of any subtype, and a
59: method with a parameter of a given type may be invoked with an argument
60: of any subtype of that type.
62: Further explanation ...
63: Substitutability is a principle in object-oriented programming that states
64: that, in a computer program, if S is a subtype of T, then objects of type
65: T may be replaced with objects of type S (i.e., an object of the type T
66: may be substituted with its subtype object of the type S) without altering
67: any of the desirable properties of that program (correctness, task
68: performed, etc.). More formally, the Liskov substitution principle (LSP)
69: is a particular definition of a subtyping relation, called (strong)
70: behavioral subtyping, that was initially introduced by Barbara Liskov in
71: a 1987 conference keynote address entitled Data Abstraction and Hierarchy.
72: It is a semantic rather than merely a syntactic relation because it
73: intends to guarantee semantic interoperability of types in a hierarchy,
74: object types in particular. Barbara Liskov and Jeannette Wing formulated
75: the principle succinctly in a 1994 paper as follows:
77: Subtype Requirement:
78: Let p(x) be a property provable about objects x of type T. Then p(y) should
79: be true for objects y of type S where S is a subtype of T.
80: */