1

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).

4
  • 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. Commented Jul 10, 2011 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. Commented Jul 10, 2011 at 7:38
  • @parsa Compare with this: val m: A = new B(); m.asInstanceOf[B]. Hopefully that will make some sense. Commented Jul 10, 2011 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. Commented Jul 10, 2011 at 9:53

2 Answers 2

6

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.

Sign up to request clarification or add additional context in comments.

Comments

4

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

2 Comments

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 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.