... To expand on that: The class implements Roamable and so you can cast an instance of the class to the type Roamable. So, yes.
I notice that people who are new to Java sometimes invent new "rules" which don't actually exist. This is a natural thing for people to do. But there's no rule which requires classes and interfaces to be "related", that's not even a Java term. One of the purposes of the certification exams is to stretch your understanding of the language so that you don't have to do that.
Paul Clapham wrote:... To expand on that: The class implements Roamable and so you can cast an instance of the class to the type Roamable. So, yes.
Wait, what? What class implements Roamable? Tablet does, but no one is creating a Tablet - they're creating a Phone. The class Phone does not implement Roamable.
OK, technically they're creating a Phone as an instance field of a Tablet. So it will only happen when you create a Tablet. But, the problem is with the Phone instance and casting, not the Tablet.
Everything in the program will compile fine. So it's all legal Java, from that perspective. When you run it, the Phone instance will be created without any problems. However, immediately after that, when the Phone instance is cast to Roamable, you will get a ClassCastException. Because Phone is not Roamable.
Paul Clapham wrote:But there's no rule which requires classes and interfaces to be "related", that's not even a Java term.
I assume you mean, in the context of whether a cast is allowable at compile time, or whether it succeeds at run time. And actually there are rules, and the JLS does use the term "related" as shorthand for some of those rules.
JLS Example 5.5-1. Casting for Reference Types wrote:Here, the first compile-time error occurs because the class types Long and Point are unrelated (that is, they are not the same, and neither is a subclass of the other), so a cast between them will always fail.
JLS 5.1.6. Narrowing Reference Conversion wrote:A narrowing reference conversion treats expressions of a reference type S as expressions of a different reference type T, where S is not a subtype of T. The supported pairs of types are defined in §220.127.116.11. Unlike widening reference conversion, the types need not be directly related. However, there are restrictions that prohibit conversion between certain pairs of types when it can be statically proven that no value can be of both types.
For the specifics though, we need to go here:
JLS 18.104.22.168. Allowed Narrowing Reference Conversion wrote:
One of the following cases applies:
5. S is an interface type, T is a class type, and T does not name a final class.
6. S is an interface type, T is a class type, and T names a final class that implements the interface named by S.
The code here deals with case 5, which means that the cast is legal at compile time, even though it fails at run time. However, if the class Phone had been final, then we would be in case 6, and the cast would not have been legal. (There also would have been problems because Tablet could not extend Phone if Phone were final... but let's assume you fixed that; it's a different issue.). The point is, yes there are rules that govern this stuff, and they do have an effect on whether code compiles, or whether it runs without error.
I can't take it! You are too smart for me! Here is the tiny ad: