Unformatted text preview:

6.170 Recitation #5: Subtypes and InheritanceWhat is true subtyping?Substitution PrincipleA More Elaborate Example: BicycleTeam Building Exercise6.170 Recitation #5: Subtypes and Inheritance What is true subtyping? True Subtyping is not exactly the same as Inheritance. As seen in an earlier lecture, class A is a true subtype of class B if and only if, whenever B is expected, A can be used. For example, let's consider the following two classes Square and Rectangle: class Square { public int width; } class Rectangle { public int width,height; } Square is not a true subtype of Rectangle, and Rectangle is also not a true subtype of Square. To see this, let's consider the following 2 functions: int calculateArea (Square x) { return (x.width)*(x.width); } int calculateCircumference (Rectangle x) { return 2*(x.width+x.height); } calculateArea() expects a Square. If we give it a Rectangle with width==2 and height==3, its answer will be 4 rather than the correct answer of 6. So Rectangle is not a true subtype of Square. calculateCircumference() expects a Rectangle. We can't give it a Square, since it won't be able to find the height field. So Square is not a true subtype of Rectangle either. In general, how do we decide if a type is a true subtype of another type? One way to be more rigorous about it is to apply the substitution principle: Substitution Principle Basically, it states that if code depends on an object of the supertype, then you can substitute an object of a subtype without breaking the system.The methods of a subtype must hold certain relationships to the methods of the supertype, and the subtype must guarantee that any properties of the supertype (such as representation invariants or specification constraints) are not violated by the subtype. There are three necessary properties: • 1. For each method in the supertype, the subtype must have a corresponding method. (The subtype is allowed to introduce additional, new methods that do not appear in the supertype.) • 2. Each method in subtype that corresponds to one in the supertype must require equal or less than the supertype method. (that is, the method in the subtype has a equal or weaker precondition). • 3. Each method in subtype that corresponds to one in the supertype must achieve equal or more than the supertype method. (that is, the method in the subtype has a equal or stronger postcondition). What does condition 2 mean? What exactly must the method in the subtype satisfy? Here are some necessary conditions: • It must not have additional "requires" clause. • Each existing "requires" clause must be no more strict than the one in the supertype method. • Each argument type must be supertypes of the ones in the supertype method. (This feels strange, but it actually makes sense, because any arguments passed to the supertype method will then surely be legal arguments to the subtype method) What does condition 3 mean? What exactly must the method in the subtype satisfy? Here are some necessary conditions: • The subtype method must not throw more exceptions • The subtype method must not modify more variables • Each clause describing the result of the supertype method must be matched by an equal or stronger clause in the subtype method's description. • The subtype method's return type must be a subtype of the supertype method's return type. For example, consider the following 2 methods: class B { Bicycle f(Bicycle arg); } class A { RacingBicycle f(Vehicle arg); }Method B.f takes a Bicycle as its argument, but A.f can accept any Vehicle (which includes all Bicycles). Method B.f returns a Bicycle as its result, but A.f returns a RacingBicycle (which is itself a Bicycle). So A.f is a refinement of B.f. (And if everything else in class A are refinement of class B also, then class A is a true subtype of class B) A More Elaborate Example: Bicycle class Bicycle { private int framesize; private int chainringGears; private int freewheelGears; ... // returns the number of gears on this bicycle public int gears() { return chainringGears * freewheelGears; } // returns the cost of this bicycle public float cost() { ... } // returns the sales tax owed on this bicycle public float salesTax() { return cost() * .0825; } // effects: transports the rider from work to home public void goHome() { ... } } class LightedBicycle { private int framesize; private int chainringGears; private int freewheelGears; private BatteryType battery; ... // returns the number of gears on this bicycle public int gears() { return chainringGears * freewheelGears; } // returns the cost of this bicycle float cost() { ... } // returns the sales tax owed on this bicycle public float salesTax() { return cost() * .0825; } // effects: transports the rider from work to home public void goHome() { ... } // effects: replaces the existing battery with the argument b public void changeBattery(BatteryType b) { ... } }Java and other programming languages use subclassing to overcome these difficulties. Subclassing permits reuse of implementations and overriding of methods. A better implementation of LightedBicycle is class LightedBicycle extends Bicycle { private BatteryType battery; // returns the cost of this bicycle float cost() { return super.cost() + battery.cost(); } // effects: replaces the existing battery with the argument b public void changeBattery(BatteryType b) { ... } } LightedBicycle need not implement methods and fields that appear in its superclass Bicycle; the Bicycle versions are automatically used by Java when they are not overridden in the subclass. Consider the following implementations of the goHome method. If these are the only changes, are LightedBicycle and RacingBicycle true subtypes of Bicycle? class Bicycle { ... // requires: windspeed < 20mph && there is daylight // effects: transports the rider from work to home void goHome() { ... } } class LightedBicycle { ... // requires: windspeed < 20mph // effects: transports the rider from work to home void goHome() { ... } } class RacingBicycle { ... // requires: windspeed < 20mph && there is daylight // effects: transports the rider from work to home // in less than 10 minutes && gets the rider sweaty void goHome() { ... } } To answer that question, recall the definition of


View Full Document

MIT 6 170 - Subtypes and Inheritance

Download Subtypes and Inheritance
Our administrator received your request to download this document. We will send you the file to your email shortly.
Loading Unlocking...
Login

Join to view Subtypes and Inheritance and access 3M+ class-specific study document.

or
We will never post anything without your permission.
Don't have an account?
Sign Up

Join to view Subtypes and Inheritance 2 2 and access 3M+ class-specific study document.

or

By creating an account you agree to our Privacy Policy and Terms Of Use

Already a member?