I found following question in my study book and a bit confused:
Given the following code, which option, if used to replace /* INSERT CODE
HERE */, will enable a reference variable of type Roamable to refer to an object of the
Phone class? (Select 1 option.)
interface Roamable{}
class Phone {}
class Tablet extends Phone implements Roamable {
//INSERT CODE HERE
}
Options are:
Roamable var = new Phone();
Roamable var = (Roamable)Phone();
Roamable var = (Roamable)new Phone();
Because interface Roamable and class Phone are unrelated, a reference variable
of type Roamable can’t refer to an object of class Phone.
I thought the correct option is 4, however it says it is 3.
But, Phone doesn't implement Roamable interface, so you can't cast, can you?
解决方案
The correct answer is 3: The compiler sees only that a Phone is being cast to a Roamable and that Phone is not final, so it thinks that the object being cast, although referred to as Phone may be a subclass of Phone that does implement Roamable, so no compile-time error or warning is issued.
5.5.1. Reference Type Casting
Given a compile-time reference type S (source) and a compile-time reference type T (target), a casting conversion exists from S to T if no compile-time errors occur due to the following rules.
If T is an interface type:
If S is not a final class (§8.1.1), then, if there exists a supertype X of T, and a supertype Y of S, such that both X and Y are provably distinct parameterized types, and that the erasures of X and Y are the same, a compile-time error occurs.
Otherwise, the cast is always legal at compile time (because even if S does not implement T, a subclass of S might).
If S is a final class (§8.1.1), then S must implement T, or a compile-time error occurs.
The following code compiles:
interface Roamable{}
class Phone {}
class Tablet extends Phone implements Roamable {
Roamable var = (Roamable)new Phone(); // Compiles
}