5

if:

interface I{}

class A implements I{}

class B extends A{}

class C extends B{}

A a = new A();
B b = new B();

Why a = (B)(I)b; is correct
but b = (B)(I)a; is false?

I find casting to be very confusing, what is the best way to understand if I can down cast or up cast an object?

OPK
  • 4,120
  • 6
  • 36
  • 66
  • 4
    Why are you casting to `I` at all? If you removed all mention of `I`, and just had `a = (B) b;` and `b = (B) a;` would that be clear to you? – Jon Skeet Jan 03 '15 at 21:21
  • @JonSkeet this is a java exam question i am also very confused why they casting an Interface "I" – OPK Jan 03 '15 at 21:22
  • Both of those casts are correct (as in they both compile and won't fail at runtime). What specifically are you seeing that makes them not compile in Java 7+? – Makoto Jan 03 '15 at 21:34
  • @Makoto the answer says the second one will fail at run time but i have no idea why. – OPK Jan 03 '15 at 21:35
  • This is something that's easily verifiable; the cast doesn't fail at runtime either. – Makoto Jan 03 '15 at 21:36
  • @taimeili123 Please see my updated answer. Let me know if that answers your question. – Jobs Jan 03 '15 at 22:36

2 Answers2

1

Your class hierarchy looks like this:

C -> B -> A -> I

Object x can be casted to class Y, if runtime type of x is subclass of Y. Or, in other words, if there is a path from runtime type of x to Y. By "runtime type" i mean the type of object (the one used when constructing object) as opposed to type of variable (the one from variable declaration).

This is valid:

b = new B();
(B)(I)b;

Object stored in b has type B. It's casted to I and then back to B. B is a subclass of both of them. Cast to I doesn't actually do anything and is meant only to confuse you.

However, neither of those is valid:

a = new A();
(B)(I)a;
(B)a;

They will both fail with exception: java.lang.ClassCastException: A cannot be cast to B. a has type A which is not a subclass of B. There is a relation between A and B, but it's in the opposite direction - B is a subclass of A.

For more detailed explanation see here: http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

Piotr Praszmo
  • 17,928
  • 1
  • 57
  • 65
1

The only thing of relevance to answering the question in your coding sample is the following:

class B extends A{}

This means that B is a subclass of A. Subclasses can be cast to super class types, but super class cannot be cast to subclass types.

Therefore, A cannot be cast to type B.

Why? Think about the logic this way:

enter image description here is a type of Programming_language, but Programming_language is not a type of enter image description here

Jobs
  • 3,317
  • 6
  • 26
  • 52