Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

i have the following Classes and interfaces:

public interface if1 {}
public class ifTest implements if1 {}

public class HelloWorld {
     public static void main(String[] args) {
          //why does the following cast not work (Compiler error)  
          ifTest var3 = (if1) new ifTest();
     }
}

Why does this cast not work? I get the following compile error: "Type mismatch: cannot convert from if1 to ifTest"

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
320 views
Welcome To Ask or Share your Answers For Others

1 Answer

Inheritance denotes an is-a relationship. Any object of IfTest is-an If1. However, a reference of type If1 does not necessarily refer to an object of type IfTest.

In a textbook scenario, any Dog is an Animal but any Animal is not a Dog (it might be a zebra, elephant, deer, etc).

Casting takes the form:

A a = (B) c;

There are 2 steps involved:

  1. You have any object c that is cast to type B.
  2. That instance of B is then assigned to variable a (where A is a type that must be either equal to B or a super class of B for the compiler to be happy and for no ClassCastExceptions to occur at runtime.

Continuing the animal metaphor, you are casting Dog to an Animal in step 1, but then trying to assign that instance of an Animal to a variable of type Dog, which the compiler knows is not allowed.

The following would work because it casts IfTest to If1 and then assigning that If1 to IfTest.

if1 var3 = (if1) new ifTest();

EDIT As Lew points out in his comment below, this is what is referred to as a widening cast (because it goes from a specific type to a more generic, "wider" type. In this instance, the cast is not necessary because the compiler knows all references to objects of type IfTest by definition are also If1.

A more practical example would be if you had a reference to the interface and wanted to cast it to a IfTest. In this case, it's a "narrowing" cast because you're going from the generic type to a more specific, "narrower" type.

if1 var1 = (if1) new ifTest();
if (var1 instanceOf ifTest) {
    ifTest var2 = (ifTest) var1;
}

Note the use of the instanceof to to ensure that var1 is in fact an instance of IfTest. While we know it is, in a real-world application If1 might have multiple subtypes so this will not always be true. The check prevents the cast from throwing a run-time ClassCassException.

TLDR: The important thing to know is what is inside the parenthesis must be a type the compiler knows can be assigned to the variable being assigned to.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...