Worksheet Subtyping
Table of Contents
1. Dangling Pointers
Answer all of the optional questions on the worksheet from week 1 of the course.
2. Dynamic Dispatch And Covariant Subtyping In Java
Consider the following program in Java. What will be printed when it runs?
Verify your answer by compiling and running the program.
interface I { void f (); } class A implements I { public void f () { System.out.println ("A"); } } class B extends A { public void f () { System.out.println ("B"); } } public class Dispatch1 { public static void main (String[] args) { I[] arr1 = new I[] { new A (), new B () }; A[] arr2 = new A[] { new A (), new B () }; A[] arr3 = new B[] { new B (), new B () }; for (int n = 0; n < arr1.length; n++) { arr1[n].f (); arr1[n] = new A (); } for (int n = 0; n < arr2.length; n++) { arr2[n].f (); arr2[n] = new A (); } for (int n = 0; n < arr3.length; n++) { arr3[n].f (); arr3[n] = new A (); } } }
3. Subtyping Questions
3.1. Symmetric?
Is it true that subtyping is a symmetric relation?
I.e., if Y<:X
then X<:Y
.
If you answer no, give an example Java or Scala program that proves your point (it should fail to compile).
3.2. Transitivity?
Suppose W<:X
, X<:Y
, and List[Y]<:Z
.
Is it the case that List[W]<:Z
?
3.3. Downcasting
Something is wrong with the method convert
in the following Java program.
Does it fail at compile time or at runtime?
Verify your answer by compiling and (perhaps) running the program.
public class Downcast { static class A { int x; } static class B extends A { int y; } static B convert (A p) { B result = (B) p; return result; } public static void main (String[] args) { A r = new A (); r.x = 5; B s = convert (r); System.out.println (s); } }
4. Subtyping And Variance In Scala
4.1. Covariant Lists
Verify that the List
type is covariant in Scala by entering the following Scala program into the Scala REPL.
class B: def f (x:Int) : Int = 1 class C extends B: override def f (x:Int) : Int = 2 def g () : Int = 3 val xs1:List[B] = List (new B, new B) val xs2:List[C] = List (new C, new C) val xs3:List[B] = List (new B, new C) val xs4:List[B] = xs2 xs4 (1).f (0)
4.2. Invariant Arrays
Verify that the Array
type is invariant in Scala by entering the following Scala program into the Scala REPL.
class B: def f (x:Int) : Int = 1 class C extends B: override def f (x:Int) : Int = 2 def g () : Int = 3 val xs1:Array[B] = Array (new B, new B) val xs2:Array[C] = Array (new C, new C) val xs3:Array[B] = Array (new B, new C) val xs4:Array[B] = xs2 xs4 (0) = new B xs2 (0).g ()