241-423 advanced data structures and algorithms
DESCRIPTION
241-423 Advanced Data Structures and Algorithms. Objective explain how subtyping/subclassing and generics are combined in Java introduce covariance and contravariance. Semester 2, 2013-2014. 7 . Subtypes/subclassing and Generics. Contents. The Substitution Principle - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/1.jpg)
ADSA: Subtypes/7 1
241-423 Advanced Data Structures and Algorithms
• Objective– explain how subtyping/subclassing and
generics are combined in Java– introduce covariance and contravariance
Semester 2, 2013-2014
7. Subtypes/subclassing and Generics
![Page 2: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/2.jpg)
ADSA: Subtypes/7 2
Contents
1. The Substitution Principle
2. Subtyping of An Entire Collection
3. Subtyping/subclassing Terminology
4. Covariance: ? extends
5. Contravariance: ? super
6. The Get and Put Principle (PECS)
7. No Instance Creation with ?
![Page 3: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/3.jpg)
ADSA: Subtypes/7 3
1. The Substitution Principle
• You can assign an object of any subclass to a class reference (variable).
Integer i = new Integer(6);
Number n = i; Number
Float Integer
extends
Number
reference
Integer
object
n
i
![Page 4: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/4.jpg)
ADSA: Subtypes/7 4
Apple a = new Apple();
Fruit f = a;Fruit
Apple Strawberry
extends
Fruit
reference
Apple
object
f
a
![Page 5: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/5.jpg)
ADSA: Subtypes/7 5
Subtyping of Collection Elements
• We can add an integer or a double to a collection of Numbers, because Integer and Double are subclasses of Number.
List<Number> nums = new ArrayList<Number>();
nums.add(2);
nums.add(3.14); // OK
![Page 6: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/6.jpg)
ADSA: Subtypes/7 6
List<Number>
reference
Integer
object
nums . . .
Double
object
List<Number> object
Number
references
3.142
![Page 7: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/7.jpg)
ADSA: Subtypes/7 7
2. Subtyping of An Entire Collection
• You might think that since Integer is a subclass of Number, then List<Integer> is a subclass of List<Number>. NO!!!
List<Integer> ints = Arrays.asList(2, 3);
List<Number> nums = ints; // compile-time err
![Page 8: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/8.jpg)
ADSA: Subtypes/7 8
List<Number>
reference
Integer
object
nums . . .
Double
object
List<Integer> object
Integer
references
32
ints
![Page 9: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/9.jpg)
ADSA: Subtypes/7 9
Why?
• It's to prevent run-time errors such as the following:
List<Integer> ints = new Integer[] {1,2};
List<Number> nums = ints;
// compile-time error
nums.add(3.12); // run-time error (not reached)
![Page 10: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/10.jpg)
ADSA: Subtypes/7 10
Another Example
List<Apple> apples = ...;
List<Fruit> fruits = apples; // compile-time error
![Page 11: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/11.jpg)
ADSA: Subtypes/7 11
• Just to confuse matters, Integer[] is a subclass of Number[].
Integer[] ints = new Integer[] {1,2,3};
Number[] nums = ints; // OK
nums[2] = 3.12; // run-time error (will be reached)
Arrays are Different
![Page 12: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/12.jpg)
ADSA: Subtypes/7 12
3. Subtyping/subclassing Terminology
• Covariance: a class reference (variable) can point to a 'narrower' subclass object– e.g. Fruit f = new Apple();– narrower means "more specific"
• Contravariance: a class reference (variable) can point to a 'wider' superclass object– e.g from Integer to Number– not common in Java
• Invariant: not able to convert
![Page 13: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/13.jpg)
ADSA: Subtypes/7 13
• Arrays are covariant:– Integer[] is also a Number[]
• Basic Generic classes are not covariant and not contravariant: they are invariant
• For example:– List<Integer> is not a subclass List<Number>– Also List<Number> is not a subclass of
List<Integer>
![Page 14: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/14.jpg)
ADSA: Subtypes/7 14
Adding Covariance and Contravariance
• It is useful to allow covariance and contravariance in collections, so the Java designers added:– ? extends (extends wildcard) for covariance
– ? super (super wildcard) for contravariance
![Page 15: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/15.jpg)
ADSA: Subtypes/7 15
4. Covariance: ? extends
List<Integer> ints = Arrays.asList(1,2);
List<? extends Number> nums = ints; // OK
•"? extends Number" means that it is OK to assign a subclass collection of Number to nums
– in this case, a collection of Integers
![Page 16: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/16.jpg)
ADSA: Subtypes/7 16
• But we cannot put elements into the collection...
List<Integer> ints = Arrays.asList(1,2);
List<? extends Number> nums = ints; // OK
nums.add(3.12); // compile-time error
• This is the array situation, but with one big difference–the error is caught at compile-time
![Page 17: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/17.jpg)
ADSA: Subtypes/7 17
Another ? Extends Example
List<Apple> apples = new ArrayList<Apple>();
List<? extends Fruit> fs = apples; // OK
fs.add(new Strawberry()); //compile-time err
•The code won't compile even if we try to add an Apple or a Fruit instance
fs.add(new Apple()); //compile-time err
fs.add(new Fruit()); //compile-time err
![Page 18: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/18.jpg)
ADSA: Subtypes/7 18
• The restriction is because the compiler only knows that fs refers to a collection subclass of Fruit, but not which one.
![Page 19: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/19.jpg)
ADSA: Subtypes/7 19
• The only thing we can add is null: fruits.add(null); // ok
• We can get data out of the structure but only as a Fruit instance (the ? extends class):Fruit get = fruits.get(0);
![Page 20: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/20.jpg)
ADSA: Subtypes/7 20
Summary of ? extends
• It allows the assignment of a subclass collection to a superclass collection reference, but no element assignments are possible– quite restrictive
• Values can be removed, as instances of the superclass– useful Good for
'getting'
Good for
'getting'
![Page 21: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/21.jpg)
ADSA: Subtypes/7 21
5. Contravariance: ? superList<Object> objs = Arrays.<Object>asList(1,"two");
List<? super Integer> vals = objs;
vats.add(3); // ok
•? super allows a superclass collection of Integer to be assigned to vals
– in this case, a list of Objects
•And you can add subclass elements to the collection later.
![Page 22: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/22.jpg)
ADSA: Subtypes/7 22
Another ? super example
List<Fruit> fruits = new ArrayList<Fruit>();
List<? super Apple> apps = fruits;
apps.add(new Apple()); // OK
apps.add(new GreenApple()); // OK
apps.add(new Fruit()); // compile-time error
apps.add(new Object()); // compile-time error
•Only subclass elements of Apple can be added.
![Page 23: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/23.jpg)
ADSA: Subtypes/7 23
Why?
• The compiler knows that apps refers to a superclass collection of Apple.
• It does not know which class, but all superclasses of Apple can store subclasses of Apple as new elements.
![Page 24: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/24.jpg)
ADSA: Subtypes/7 24
Get Restriction with ? Super
• You can only get elements out of a ? super object as values of class Object:
Object ob1 = fruits.get(0);
Object ob2 = fruits.get(1);
Fruit f = (Fruit) fruits.get(0); // compile-time err
![Page 25: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/25.jpg)
ADSA: Subtypes/7 25
Another Example
List<Object> objs = Arrays.<Object>asList(1,"two");
List<? super Integer> ints = objs;
String str = "";
for (Object obj : ints)
str += obj.toString(); // Object method
// str is "1two"
![Page 26: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/26.jpg)
ADSA: Subtypes/7 26
Summary of ? super
• It allows the assignment of a superclass collection to a subclass reference, and further subclass additions are possible– useful
• Values can only be removed as Object instances– quite restrictive
Good for
'putting'
Good for
'putting'
![Page 27: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/27.jpg)
ADSA: Subtypes/7 27
6. The Get and Put Principle (PECS)
– use ? extends when you only get values out of a collection; i.e. is a producer
– use ? super when you only put values into a collection; i.e. is a consumer
– don't use a wildcard when you both get and put
• PECS comes from "Producer Extends, Consumer Super"
![Page 28: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/28.jpg)
ADSA: Subtypes/7 28
? extends Function example
public static double sum( Collection<? extends Number> nums)
{
double s = 0.0;
for (Number num : nums)
s += num.doubleValue();
return s;
}
PECS
producer(a Number method)
![Page 29: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/29.jpg)
ADSA: Subtypes/7 29
• The following calls are legal:
List<Integer> ints = Arrays.asList(1, 2, 3);
double d = sum(ints); // == 6.0;
List<Double> doubles = Arrays.asList(2.78, 3.14);
double d = sum(doubles); // == 5.92;
List<Number> nums = Arrays.<Number>asList(1, 2, 2.78, 3.14);
double d = sum(nums); // == 8.92;
• The first two calls would not be legal if ? extends was not used.
![Page 30: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/30.jpg)
ADSA: Subtypes/7 30
? super function example
public static void count( Collection<? super Integer> ints, int n)
{
for (int i = 0; i < n; i++)
ints.add(i);
}
PECS
consumer
![Page 31: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/31.jpg)
ADSA: Subtypes/7 31
• The following calls are legal:
List<Integer> ints = new ArrayList<Integer>();
count(ints, 5);
// ints.toString().equals("[0, 1, 2, 3, 4]");
List<Number> nums = new ArrayList<Number>();
count(nums, 5);
nums.add(5.0);
// nums.toString().equals("[0, 1, 2, 3, 4, 5.0]");
List<Object> objs = new ArrayList<Object>();
count(objs, 5);
objs.add("five");
// objs.toString().equals("[0, 1, 2, 3, 4, five]");
• The last two calls need ? super in count()
![Page 32: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/32.jpg)
ADSA: Subtypes/7 32
No wildcard example
public static double sumCount( Collection<Number> nums, int n)
{ count(nums, n);
return sum(nums);
}
•The nums collection is passed to both sum() and count(), so its element class must both extend Number (as sum() requires) and be super to Integer (as count() requires).
Number
Integer
? extend
? super
![Page 33: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/33.jpg)
ADSA: Subtypes/7 33
• The only two classes that satisfy both of these constraints are Number and Integer, and I picked the first.
• A sample call:List<Number> nums = new ArrayList<Number>();
double sum = sumCount(nums,5);
Number
Integer
? extend
? super
![Page 34: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/34.jpg)
ADSA: Subtypes/7 34
Using both ? extends and ? super
public static <T> void copy( List<? super Integer> dst, List<? extends Integer> src)
{ for (int i = 0; i < src.size(); i++)
dst.set(i, src.get(i));
}
•the destination list may already contains elements of any class that is a superclass of Integer
•the source list will have elements of any class that is a subclass of Integer.
PECS
![Page 35: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/35.jpg)
ADSA: Subtypes/7 35
• A sample call:
List<Object> objs = Arrays.<Object>asList(2, 3.14, "four");
List<Integer> ints = Arrays.asList(5, 6);
Collections.copy(objs, ints);
// objs is "[5, 6, four]"
![Page 36: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/36.jpg)
ADSA: Subtypes/7 36
7. No Instance Creation with ?
• For example, the following are illegal:
List<?> list = new ArrayList<?>();
// compile-time error
Map<String, ? extends Number> map = new HashMap<String, ? extends Number>();
// compile-time error
![Page 37: 241-423 Advanced Data Structures and Algorithms](https://reader035.vdocuments.mx/reader035/viewer/2022062322/568147eb550346895db52393/html5/thumbnails/37.jpg)
ADSA: Subtypes/7 37
• Usually we create a concrete collection first, even if we use wildcards later:
List<Number> nums = new ArrayList<Number>();
List<? super Number> sink = nums; // OK
for (int i=0; i<10; i++)
sink.add(i);