Lecture 26
Subtyping for OOP;
Generics vs. Subtyping
Programming Languages
UW CSE 341 - Winter 2023
Now…
Use what we learned about subtyping for records and functions to understand subtyping for class-based OOP
Recall:
Classes vs. Types
An object is…
Actual Java…
Compare/contrast to what our “theory” allows:
Optional: More details
Java is sound-y: Does not allow subtypes to do things that would lead to “method missing” or accessing a field at the wrong type
Confusing (?) Java example:
this is special
class A {
int m(){ return 0; }
}
class B extends A {
int x;
int m(){ return x; }
}
What are generics good for?
Some good uses for parametric polymorphism:
let compose g h = fun x -> g (h x)
(* compose : ('b -> 'c) -> ('a -> 'b) -> ('a -> 'c) *)
val length : 'a list -> int
val map : ('a -> 'b) -> 'a list -> 'b list
val swap : ('a * 'b) -> ('b * 'a)
Generics in Java
class Pair<T1,T2> {
T1 x;
T2 y;
Pair(T1 _x, T2 _y){ x = _x; y = _y; }
Pair<T2,T1> swap() {
return new Pair<T2,T1>(y,x);
}
…
}
Subtyping is not good for this
class MehPair {
Object x;
Object y;
MehPair(Object _x, Object _y){ x=_x; y=_y; }
MehPair swap() { return new MehPair(y,x); }
}
// error caught only at run-time:
String s = (String)(new MehPair("hi",4).y);
What is subtyping good for?
Some good uses for subtype polymorphism:
Wanting both
Example
Method that takes a list of points and a circle (center point, radius)
Basic method signature:
Java implementation straightforward assuming Point has a distance method:
List<Point> inCircle(List<Point> pts,
Point center,
double r) { … }
List<Point> result = new ArrayList<Point>();
for(Point pt : pts)
if(pt.distance(center) < r)
result.add(pt);
return result;
Subtyping?
List<Point> inCircle(List<Point> pts,
Point center,
double r) { … }
Generics?
List<Point> inCircle(List<Point> pts,
Point center,
double r) { … }
<T> List<T> inCircle(List<T> pts,
Point center,
double r) { … }
Bounds
<T> List<T> inCircle(List<T> pts,
Point center,
double r) where T <: Point
{ … }
Real Java
<T extends Pt> List<T> inCircle(List<T> pts,
Pt center,
double r) {
List<T> result = new ArrayList<T>();
for(T pt : pts)
if(pt.distance(center) < r)
result.add(pt);
return result;
}