Java distinguishes an object from an interface that is not implemented

I found the following question in my tutorial and am a bit confused:

Given the following code, what option, if used to replace /* INSERT CODE HERE */ , will allow a reference variable of the Roamable type Roamable refer to the Phone object class? (Select option 1).

 interface Roamable{} class Phone {} class Tablet extends Phone implements Roamable { //INSERT CODE HERE } 

Options:

  • Roamable var = new Phone();
  • Roamable var = (Roamable)Phone();
  • Roamable var = (Roamable)new Phone();
  • Since the Roamable interface and class Phone not connected, the reference variable of the Roamable type cannot refer to an object of the Phone class.

I thought the correct option is 4, however he says it is 3.

But, Phone does not implement the Roamable interface, so you cannot distinguish it, right?

+6
source share
2 answers

Correct answer 3 : the compiler only sees that a Phone discarded in Roamable and that Phone not final, so he believes that the object that runs, although called Phone can be a subclass of Phone that implements Roamable , so no error or warning compilation error.

According to JLS chapter 5

5.5.1. Reference Type

Given the reference compile-time type S (source) and the compile-time reference type T (target), a cast conversion exists from S to T if compile-time errors do not occur due to the following rules. If T is the type of interface:

If S is not a finite class (ยง8.1.1), then if there is a supertype X from T and a supertype Y from S such that both X and Y are predictable different parameterized types and that the erasures of X and Y are the same, a time error occurs compilation.

Otherwise, listing is always legal at compile time (because even if S does not implement T, there may be a subclass of S).

If S is a finite 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 } 
+10
source

The answer will be 4

a

 1 is incorrect(explanation --> 4) 2 is incorrect syntax 3 is incorrect typecast. 

Note that answer 3 is valid as long as it is roughly compilation . When you say that you have an instance of the Phone class, you can type cast in Tablet (Just like you can use Object for String ). And since Tablet implements Roamable , you can very well use the Roamable link to link it. Problem will occur at runtime , because Object really is of type Phone .

This is only one of the binders (in the current context) that allows you to successfully compile. But as God said in his answer in general

If we attribute the reference S (non final) to compile time to compile the time job T, then compilation will succeed as even if S does not implement T, a subclass of S might . If S is a finite class, then S must implement T, or a compile-time error occurs.

Actually there is no need for a Tablet class extending the Phone class. While the phone class not final compilation will succeed

 interface Roamable{} class Phone {} class Tablet implements Roamable { Roamable var = (Roamable)new Phone(); // Compiles } 
+1
source

All Articles