Questions and Completion
There is nothing to hand in for the worksheet, but you should definitely work through it in order to prepare for the quiz and homework.
If you have questions as you go through this worksheet, please feel free to post them on Discord.
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 ();
}
}
}Subtyping Questions
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).
Transitivity?
Suppose W<:X, X<:Y, and List[Y]<:Z. Is it the case that List[W]<:Z?
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);
}
}Subtyping And Variance In Scala
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)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 ()