DOC PREVIEW
UW CSE 341 - Lecture Notes

This preview shows page 1-2 out of 5 pages.

Save
View full document
View full document
Premium Document
Do you want full access? Go Premium and unlock all 5 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 5 pages.
Access to all documents
Download any document
Ad free experience
Premium Document
Do you want full access? Go Premium and unlock all 5 pages.
Access to all documents
Download any document
Ad free experience

Unformatted text preview:

CSE341, Fall 2011, Lecture 26 SummaryStandard Disclaimer: This lecture summary is not necessarily a complete substitute for attending class,reading the associated code, etc. It is designed to be a useful resource for students who attended class andare later reviewing the material.This lecture applies the general concepts of record and function subtyping from the last lecture to object-oriented languages, mostly Java. We will see that:• Record and function subtyping are excellent guides to what should be allowed in statically typedobject-oriented languages to prevent “field missing” and “method missing” errors.• But Java has two key differences worth exploring:– It uses class and interface names for types, which is convenient and/but prevents some subtypingthat would be sound.– It does not support contravariant arguments on methods. Instead it supports static overloadingbased on the types of method arguments.• self/this is special with respect to subtyping: It is covariant in subclasses even though we sometimesthink of it as an extra argument to methods.Basic Subtyping for Objects and Java’s Restrictions ThereofAn object is basically a record holding fields (which we assume here are mutable) and methods. We assumethe “slots” for methods are immutable: If an object’s method m is implemented with some code, then thereis no way to mutate m to refer to different code. (An instance of a subclass could have different code for m,but that’s different than mutating a record field.)With this perspective, sound subtyping for objects follows from sound subtyping for records and functions:• A subtype can have extra fields.• Because fields are mutable, a subtype cannot have a different type for a field.• A subtype can have extra methods.• Because methods are immutable, a subtype can have a subtype for a method, which means the methodin the subtype can have contravariant argument types and a covariant result result type.That said, object types in Java and C# do not look like record types and function types. For example, wecannot write down a type that looks something like:{fields : x:real, y:real, ...methods: distToOrigin : () -> real, ...}Instead, we reuse class names as types where if there is a class Foo, then the type Foo includes in it all fieldsand methods implied by the class definition (including superclasses). And, as discussed previously, we alsohave interfaces, which are more like record types except they do not include fields and we use the nameof the interface as a type. Subtyping in Java and C# includes only the subtyping explicitly stated via thesubclass relationship and the interfaces that classes explicitly indicate they implement (including interfacesimplemented by superclasses).All said, this approach is more restrictive than subtyping requires, but since it does not allow anything itshould not, it soundly prevents “field missing” and “method missing” errors. In particular:1• A subclass can add fields but not remove them• A subclass can add methods but not remove them• A subclass can override a method with a covariant return type• A class can implement more methods than an interface requires or implement a required method witha covariant return typeShadowing FieldsBecause fields are mutable, we know a subtype cannot have a different type for a field than a supertype.So it is surprising that Java actually allows a class to declare a field with the same name as a field alreadydeclared in a superclass. For example, this code is allowed in Java:class Color { String colorName; }class FancyColor extends Color { double shade; }class Point { ... }class ColorPoint extends Point {Color color;...}class MyColorPoint extends ColorPoint {FancyColor color;...}It would not be sound to allow the MyColorPoint class to change the color field to hold a FancyColor andhave code assume this. After all, methods inherited from ColorPoint could assign color to hold instancesof Color leading to errors if we then tried to read the shade field.The conundrum is actually easily solved: In Java, the declaration FancyColor color adds a different field toinstances of MyColorPoint that happens to have the same name as another field. Since it is a new, differentfield, it can have any type whatsoever, not necessarily related to the type of the other field named color.Field look-ups do not use dynamic dispatch, so any uses of color in methods of ColorPoint will still usethe color field of type Color. In MyColorPoint, the new field shadows the old one, so color will refer tothe new field. To access the old field, code can use super.color.Static OverloadingA similar but more common and convenient weirdness relates to Java’s support for having multiple methodswith the same name. Even though it would be sound, there is simply no way in Java to override a methodwith contravariant arguments. Instead, Java works like this:If a class declares a method with name m, return type t0 and argument types t1, t2, ..., tn (in that order),then:• If the superclass already has a method name m with argument types t1, t2, ..., tn (in that order), thenthis is overriding. The type-checker requires t0 to be the same as the return type in the superclassmethod or a subtype (covariant subtyping on result types).• Else this is a new method added to the subclass, not overriding, even if the superclass (or the subclass)has other methods named m.2Having multiple methods with the same name can be convenient so that you do not have to think up differentnames for similar behavior. For example, a Rational class could have methods like:void add(Rational r) {...}void add(int i) {...}void add(double d) {...}But you must take care in Java to make sure you are overriding or not overriding when you intend to. Itcan be confusing to change or reorder argument types accidentally and, as a result, have different methodswith the same name.More importantly, we need to define which method gets called when there are multiple methods with the rightname. That is, we must revise our definition of the most fundamental issue in object-oriented programming:What is the semantics of e0.m(e1,...,en)? As before, we start as follows:• Evaluate e0, ..., en to objects v0, ..., vn.• Use the (run-time) class of v0 to look up m (dynamic dispatch).But now there may be multiple choices m. Java picks the “best” choice using the static types of e1, ..., en,not the classes v0, ..., vn. This semantics is called static


View Full Document

UW CSE 341 - Lecture Notes

Documents in this Course
Macros

Macros

6 pages

Macros

Macros

6 pages

Macros

Macros

3 pages

Mutation

Mutation

10 pages

Macros

Macros

17 pages

Racket

Racket

25 pages

Scheme

Scheme

9 pages

Macros

Macros

6 pages

Load more
Download Lecture Notes
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 Lecture Notes 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 Lecture Notes 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?