Presentation is loading. Please wait.

Presentation is loading. Please wait.

ADSA: Subtypes/7 1 241-423 Advanced Data Structures and Algorithms Objective –explain how subtyping/subclassing and generics are combined in Java –introduce.

Similar presentations


Presentation on theme: "ADSA: Subtypes/7 1 241-423 Advanced Data Structures and Algorithms Objective –explain how subtyping/subclassing and generics are combined in Java –introduce."— Presentation transcript:

1 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

2 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 ?

3 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 FloatInteger extends Number reference Integer object n i

4 ADSA: Subtypes/7 4 Apple a = new Apple(); Fruit f = a; Fruit AppleStrawberry extends Fruit reference Apple object f a

5 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 nums = new ArrayList (); nums.add(2); nums.add(3.14); // OK

6 ADSA: Subtypes/7 6 List reference Integer object nums... Double object List object Number references 3.14 2

7 ADSA: Subtypes/7 7 2. Subtyping of An Entire Collection You might think that since Integer is a subclass of Number, then List is a subclass of List. NO!!! List ints = Arrays.asList(2, 3); List nums = ints; // compile-time err

8 ADSA: Subtypes/7 8 List reference Integer object nums... Double object List object Integer references 3 2 ints

9 ADSA: Subtypes/7 9 Why? It's to prevent run-time errors such as the following: List ints = new Integer[] {1,2}; List nums = ints; // compile-time error nums.add(3.12); // run-time error (not reached)

10 ADSA: Subtypes/7 10 Another Example List apples =...; List fruits = apples; // compile-time error

11 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

12 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

13 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 is not a subclass List –Also List is not a subclass of List

14 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

15 ADSA: Subtypes/7 15 4. Covariance: ? extends List ints = Arrays.asList(1,2); List 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

16 ADSA: Subtypes/7 16 But we cannot put elements into the collection... List ints = Arrays.asList(1,2); List 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

17 ADSA: Subtypes/7 17 Another ? Extends Example List apples = new ArrayList (); List 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

18 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.

19 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);

20 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'

21 ADSA: Subtypes/7 21 5. Contravariance: ? super List objs = Arrays. asList(1,"two"); List 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.

22 ADSA: Subtypes/7 22 Another ? super example List fruits = new ArrayList (); List 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.

23 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.

24 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

25 ADSA: Subtypes/7 25 Another Example List objs = Arrays. asList(1,"two"); List ints = objs; String str = ""; for (Object obj : ints) str += obj.toString(); // Object method // str is "1two"

26 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'

27 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"

28 ADSA: Subtypes/7 28 ? extends Function example public static double sum( Collection nums) { double s = 0.0; for (Number num : nums) s += num.doubleValue(); return s; } PECS producer (a Number method)

29 ADSA: Subtypes/7 29 The following calls are legal: List ints = Arrays.asList(1, 2, 3); double d = sum(ints); // == 6.0; List doubles = Arrays.asList(2.78, 3.14); double d = sum(doubles); // == 5.92; List nums = Arrays. 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.

30 ADSA: Subtypes/7 30 ? super function example public static void count( Collection ints, int n) { for (int i = 0; i < n; i++) ints.add(i); } PECS consumer

31 ADSA: Subtypes/7 31 The following calls are legal: List ints = new ArrayList (); count(ints, 5); // ints.toString().equals("[0, 1, 2, 3, 4]"); List nums = new ArrayList (); count(nums, 5); nums.add(5.0); // nums.toString().equals("[0, 1, 2, 3, 4, 5.0]"); List objs = new ArrayList (); count(objs, 5); objs.add("five"); // objs.toString().equals("[0, 1, 2, 3, 4, five]"); The last two calls need ? super in count()

32 ADSA: Subtypes/7 32 No wildcard example public static double sumCount( Collection 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

33 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 nums = new ArrayList (); double sum = sumCount(nums,5); Number Integer ? extend ? super

34 ADSA: Subtypes/7 34 Using both ? extends and ? super public static void copy( List dst, List 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

35 ADSA: Subtypes/7 35 A sample call: List objs = Arrays. asList(2, 3.14, "four"); List ints = Arrays.asList(5, 6); Collections.copy(objs, ints); // objs is "[5, 6, four]"

36 ADSA: Subtypes/7 36 7. No Instance Creation with ? For example, the following are illegal: List list = new ArrayList (); // compile-time error Map map = new HashMap (); // compile-time error

37 ADSA: Subtypes/7 37 Usually we create a concrete collection first, even if we use wildcards later: List nums = new ArrayList (); List sink = nums; // OK for (int i=0; i<10; i++) sink.add(i);


Download ppt "ADSA: Subtypes/7 1 241-423 Advanced Data Structures and Algorithms Objective –explain how subtyping/subclassing and generics are combined in Java –introduce."

Similar presentations


Ads by Google