CSE341: Programming Languages Lecture 26 Subtyping for OOP Dan Grossman Fall 2011This lecture How does subtyping for Java/C# relate to the subtyping in the last lecture? Many of the same principles but Java/C#: – Use class and interface names for types – Support static overloading instead of contravariant arguments Fall 2011 2 CSE341: Programming LanguagesWhat we have learned • A record subtype can have more fields than its supertype • A mutable record field cannot have its type change via subtyping • An immutable record field can be covariant for subtyping (depth) • Function subytping uses contravariant argument types and covariant result types Now can use this to understand how we could type-check OOP… Fall 2011 3 CSE341: Programming LanguagesAn object is… • Objects are basically records holding fields and methods – Fields are mutable – Methods are immutable functions that also have access to this / self • So we could design a type system using types very much like our record types from last lecture – Subtypes can have extra fields – Subtypes can have extra methods – Subtypes can have methods with contravariant arguments and covariant result compared to same method in supertype • Sound only because method "slots" are immutable! Fall 2011 4 CSE341: Programming LanguagesJava is more restrictive Java's object types don't look like: {fields: x:real, y:real, … methods: distToOrigin : () -> real, … } Instead: • Reuse class names as types – Type has everything implied by the class definition • Add more types with interface definitions • Have only the subtyping explicitly stated via extends and implements Cannot get "field missing" or "method missing" errors because this approach allows a subset of the subtyping that would be sound Fall 2011 5 CSE341: Programming LanguagesIn Java… • A subclass can add fields but not remove them (width) • A subclass can add methods but not remove them (width) • A subclass can override a method with a covariant return type – (Java didn't used to allow this) – Depth on immutable slot + function subtyping – But doesn't allow contravariant arguments (see later slides) • A class can implement more methods than an interface requires (width) – Also allow covariant return types Fall 2011 6 CSE341: Programming LanguagesExample (constructors and public omitted) Fall 2011 7 CSE341: Programming Languages class Pt { double x, y; double distance(Pt z) { … } Pt shift(double dx, double dy) { … } } interface Colorable { Color getColor(); void setColor(Color c); } class ColorPt extends Pt implements Colorable { Color color; Color getColor () { return this.color; } void setColor(Color c) { this.color = c; } ColorPt shift(double dx, double dy) { Pt p = super.shift(); return new ColorPt(p.x,p.y,this.color); } }Example so far • An instance of ColorPt is substitutable for any value of type Pt or type Colorable – Adds field color – Gives shift a more specific return type – Adds methods w.r.t. ColorPt and w.r.t. Colorable • What about changing the types of fields or method arguments? – Not possible in Java – For fields: to stay sound – For methods: because Java has static overloading instead – In both cases, "it type-checks" but "it" actually adds new fields/methods with the same name (kind of confusing) Fall 2011 8 CSE341: Programming LanguagesMore example (again omitting constructors) Fall 2011 9 CSE341: Programming Languages class ColorPt extends Pt implements Colorable { Color color; Color getColor () { return this.color; } void setColor(Color c) { this.color = c; } ColorPt shift(double dx, double dy) { … } } class Color extends Object { String s; } class FancyColor extends Color { double shade; } class MyColorPt extends ColorPt { T1 color; T2 getColor () { … } void setColor(T3 c) { … } } • What does redeclaring a field or method mean? • For each of T1, T2, and T3, which of Object, Color, FancyColor can they be?Field shadowing • What we have learned: Mutable fields must have the same type in subclass and superclass, so no "overriding" possible – Changing to Object or FancyColor would be unsound • Java: A field declared in the subclass can have the same name as an inherited field, but it is a new, different field – Field in subclass shadows – Can access other field with super.color – No dynamic dispatch: inherited methods use old field • So: T1 can be any type, Object, Color, FancyColor, Pizza – A different field with shadowing rules, not a subtyping issue Fall 2011 10 CSE341: Programming Languages class MyColorPt extends ColorPt { T1 color; … }Method overriding / overloading • What we have learned: If we replace a method with one of a different type, need contravariant arguments, covariant result – So T2 could be Color or FancyColor (true in Java too) – So T3 could be Color or Object (not FancyColor!) • Java: A method declared with different argument types is a different method with the same name – So T3 can be any type – If T3 is Color, then we are overriding, for any other type, we are adding a new method • Simply no syntax for overriding with contravariant args Fall 2011 11 CSE341: Programming Languages class MyColorPt extends ColorPt { T2 getColor () { … } void setColor(T3 c) { … } }Static overloading • So a Java class can have multiple methods with the same name – Called overloading • Must revisit the key question in OOP: What does e0.m(e1,…,en) mean? • As before: – Evaluate e0, …, en to v0, …, vn – Look up class of v0 (dynamic dispatch) • But now the class may have more than one m – Java: Pick the "best" one using the static types of e1, …, en • The (run-time) class of v1, …, vn is irrelevant • "Best" is complicated, roughly "least amount of subtyping" Fall 2011 12 CSE341: Programming LanguagesStatic overloading examples Fall 2011 13 CSE341: Programming Languages class Color extends Object { String s; } class FancyColor extends Color { double shade; } class MyClass { void m(Object x) { … } // A void m(Color x) { … } // B void m(FancyColor x) { … } // C void m(Color x, FancyColor y) { … } // D void m(FancyColor x, Color y) { … } // E } MyClass obj = new MyClass(…); Color c1 = new Color(…); FancyColor c2 = new FancyColor(…); Color c3 = new FancyColor(…); //
View Full Document