Take the 2-minute tour ×

Coming from a non-Java background to Scala has brought me a wide range of difficulties including this one.

scala> class A
defined class A

scala> class B extends A      
defined class B

scala> val a = new A
a: A = A@2e893a4a

scala> val b = new B
b: B = B@3a47c130

scala> a.asInstanceOf[B]
java.lang.ClassCastException: A cannot be cast to B

scala> b.asInstanceOf[A]
res1: A = B@3a47c130

I understand that ClassCastException is thrown because at runtime, a doesn't seem like a B but in fact, it is (as far as I understand). What's going on here? Any workarounds? Thanks.

Edit: how does the JVM understand that a cannot be casted to B? Does it perform some shallow comparison between a.getClass and B?

ps. I'm trying to add a private variable to a library class, and override one of the class methods that accepts a class defined in the library as argument (the class I'm trying to add the field to).

share|improve this question
You can just extend the library class and add the private variable in the extended class and use that class instead? Functions and Methods overide each other in Scala fyi. –  mythicalprogrammer Jul 10 '11 at 7:33
I'm doing as you said, I extend and add the variable. But a factory class from the library with a method that I need to override, only accepts the old class as an argument. –  parsa Jul 10 '11 at 7:38
@parsa Compare with this: val m: A = new B(); m.asInstanceOf[B]. Hopefully that will make some sense. –  user166390 Jul 10 '11 at 7:38
Replacing A with something like Animal and B with something like Dog makes the question self-explanatory. Every dog is an animal, but not every animal is a dog. –  agilesteel Jul 10 '11 at 9:53
add comment

2 Answers

up vote 6 down vote accepted

It's a hierarchy that goes down. Class A is a super class and B extends from it so it's more specific. You cannot go up the hierarchy in generalization. It's a design choice and relates to subtyping.

Is there any language where you can go up the hierarchy? Cause it seems like you're implying that there is such a language.

share|improve this answer
You're right, it's more than just not knowing Java. –  parsa Jul 10 '11 at 7:41
add comment

You cant cast A into B, only the other way around, because B is more specific than A.

share|improve this answer
Yes by definition A is a Car and B is a BMW, but with no additional fields or methods, what's prohibiting a to be seen as an B? (Or is it solely there to prevent bad software design?) –  parsa Jul 10 '11 at 7:09
@parsa The cast is a run-time operation. The type of the object is A -- not B in this case -- and thus, kaboom! If an object of type B hiding in a variable of A, then it'd be okay. It's like trying to cast Mammal (A) to a Pig (B). A Pig can Oink, but a Mammal object is more general: it can't Oink :( A Pig is, however, perfectly fine if it's treated like a Mammal. –  user166390 Jul 10 '11 at 7:33
add comment

Your Answer


