Re: Why can't I downcast in the following code
Chad wrote:
Given the following...
class X {}
class Y extends X {}
class Z extends X {}
public class Main {
public static void main(String[] args) {
X x = new X();
Y y = new Y();
Z z = new Z();
Y o6 = (Y) x; //<--error
}
}
I get this error...
run:
Exception in thread "main" java.lang.ClassCastException: X cannot be
cast to Y
at Main.main(Main.java:12)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)
I thought I could cast X to Y since they inherited. Why doesn't it
work in this case?
Inheritance, as you have discovered, does not automatically allow casting.
Upcasting works as you describe; it's downcasting that is tricky. (In Java, an "upcast" is from an inheriting or descendant type to an ancestor type, a "downcast" is from a base or ancestor type to a descendant type.)
To understand this, remember that inheritance (both the 'extends' and the 'implements' variety) represents /is-a/. A descendant thingie /is-an/ ancestor thingie, so in your example,
class X {}
class Y extends X {}
class Z extends X {}
an instance of a 'Y' /is-an/ 'X', but not necessarily would every 'X' /be-a/ 'Y'.
An instance of a 'Z' /is-an/ 'X', but not necessarily would every 'X' /be-a/ 'Z'.
In no way can you say a 'Y' /is-a/ 'Z', nor that a 'Z' /is-a/ 'Y'. Neither one is the parent of the other.
Which is exactly why downcasting is tricky. If you cast an 'X' down to a 'Y', that might actually be a 'Z' you're trying to cast. Oops - 'ClassCastException'. You cannot cast a 'Z' to a 'Y'.
In your case it's worse. You already know that 'x' /is-not-a/ 'Y'. It's a plain old 'X', with nothing of a 'Y' about it. So when you try to cast it down to a 'Y', kaboom!
And by the way, you don't get an error for that, you get an exception for that.
--
Lew