120 likes | 138 Views
Learn about the Liskov Substitution Principle (LSP) in object-oriented programming, which defines subtype substitutability. Understand its relationship with design by contract methodology and restrictions on inheritance.
E N D
COMPUTER 2430Object Oriented Programming andData Structures I
Inheritance and Polymorphism Prog 6
Liskov Substitution Principle (LSP) • In object-oriented programming, the Liskov substitution principle is a particular definition of subtype that was introduced by BarbaraLiskov in a 1987 conference keynote address entitled Data abstraction and hierarchy • Liskov's notion of "subtype" is based on the notion of substitutability
Liskov Substitution Principle (LSP) • The Liskov substitution principle is closely related to the design by contract methodology, leading to some restrictions on how contracts can interact with inheritance: • Preconditions cannot be strengthened in a subclass. Require no more! • Postconditions cannot be weakened in a subclass. Promise no less! • A function using a class hierarchy violating the principle uses a reference to a base class, yet must have knowledge of the subclasses. Such a function violates the open/closedprinciple because it must be modified whenever a new derivative of the base class is created.
Liskov Substitution Principle (LSP) Two paraphrases that capture the essence • A child can be used wherever a parent is expected • For every overridden method in a child class: Require no more Promise no less • It will be on Test 3 and the final
public class Animal { private String _id; private int numLegs; private float weight; public void grow() . . . } public class Frog extends Animal { . . . @Override public void grow() // weight determines numLegs }
public class AnimalList { private Animal[] list; private int count; public boolean add( Animal animal ) . . . } // Can FrogList be a sub-class of AnimalList? public class FrogList extends AnimalList { . . . // Can a fish be added to the list? @Override public boolean add( Animal animal ) }
public class AnimalList { private Animal[] list; private int count; // Any animal can be added to the lis. public boolean add( Animal animal ) . . . } public class FrogList extends AnimalList { . . . // Require More! @Override public boolean add( Frog frog ) }
public class AnimalList { private Animal[] list; private int count; // animal will be added to the list if not full public boolean add( Animal animal ) . . . } public class FrogList extends AnimalList { . . . // Promise Less! @Override public boolean add( Animal animal ) // do not add if not Frog }
public class BagOfFruit { private Fruit items[]; public void add ( Fruit x ) ... } public class BagOfApple extends BagOfFruit { private Apple items[]; // How to override method add? } Is a BagOfApple a BagOfFruit? Should BagOfApple be a subclass of BagOfFruit? NO!
Don't Overdo Inheritance • Is your inheritance good ? the notion of "is-a“ LSP • Circle can't inherit from Ellipse even though it "is-a” have to restrict overridden 2D "resize" • BagOfApples is not a BagOfFruit restrict overridden add or allow bananas in the apple bag