explicit casting from super class to subclass
By using a cast you're essentially telling the compiler "trust me. I'm a professional, I know what I'm doing and I know that although you can't guarantee it, I'm telling you that this animal
variable is definitely going to be a dog."
Since the animal isn't actually a dog (it's an animal, you could do Animal animal = new Dog();
and it'd be a dog) the VM throws an exception at runtime because you've violated that trust (you told the compiler everything would be ok and it's not!)
The compiler is a bit smarter than just blindly accepting everything, if you try and cast objects in different inheritence hierarchies (cast a Dog to a String for example) then the compiler will throw it back at you because it knows that could never possibly work.
Because you're essentially just stopping the compiler from complaining, every time you cast it's important to check that you won't cause a ClassCastException
by using instanceof
in an if statement (or something to that effect.)
Cast a superclass to a subclass
That's because, compiler does not know what object does your reference Building
is referring to.
So, in the below case, where you have a base class reference, pointing to sub class object: -
Building building = new Cottage();
Cottage cottage = (Cottage)building;
It would work perfectly fine. So, it's completely a runtime decision, as to whether it is a valid cast or not. Hence, compiler won't throw error for that.
Isn't it obvious that building is a reference to a Building object
before actually running the program?
No. Absolutely not. The type of object being referenced, is not known till runtime. Always remember that, Compiler always checks the reference type. Actual object type is checked at runtime.
This concept is known as Polymorphism, where you can have the same reference type to point to objects of various subtypes. You can google it, and would get lots of resources to read.
Converting Object of SuperClass to Sub Class
You can cast Child classes to Super classes but not vice versa.
If Vehicle is Super Class and Car is a Subclass then all Cars (Child) is a Vehicle (Super) but not all Vehicle is a Car.
Casting a Super Class in to a Sub Class
Why am I unable to cast
You are able to cast, but then you assign it back to MySuperClass someSubClass
which implicitly casts it back to MySuperClass
.
Use
var castedSomeSubClass = (MySubClass)someSubClass;
or
MySubClass castedSomeSubClass = (MySubClass)someSubClass;
Cast an object of super class to a sub class - down casting
A Cat
is an Animal
.
If I give you an animal (doesn't have to be cat), how would you convert it to a cat?
EDIT:
There's a way to do almost anything. Most of the time, you shouldn't. I believe a better design would eliminate the need for downcasting. But you can:
have a constructor in
Super
that takes aSub
as parameter.implement a factory of
Super
and have a method that takes aSub
as parameter.
I suggest that you expand your question, tell us exactly what you need, as I really think a more elegant solution exists.
Explicit Type Conversion of sub class object to super class in java
The explicit type casting of the reference, not the object) is redundant and some IDEs will suggest you drop it.
If you do
A a1 = (A)b;
You can still do
B b2 = (B) A;
to cast the reference back to type of B.
Note: the object is not altered in any way and is always a B
there is no scenario in java where you would need it?
The only time you need an upcast is in method selection.
void method(Object o) { }
void method(String s) { }
method("hello"); // calls method(String)
method((Object) "hello"); // calls method(Object)
Why is typecasting a super class explicit?
TL;DR:
Because compiler knows, that Dog IS-A Animal, but Animal is not a Dog (it may be, though).
class Animal { ... }
class Dog Extends Animal { ... }
class Program {
public static void main(String[] args) {
Animal a = new Dog(); //✓ compiler knows, that Dog IS-A Animal;
Dog d = new Animal(); //x compiler does NOT know, that Animal IS-A Dog
}
}
To dive in a bit deeper into your question, actually, it boils down to how the compiler (javac
, in this case) is designed.
Sure, compiler could have been designed in a less-defensive way - allowing all the casts to be validated at runtime, letting everything happen, and throwing exceptions like a firework.. and you can guess, that's bad from the perspective of engineer, type-safety, security, or just coding.
The way type narrowing (down-casting) and/or widening (up-casting) work, in Java, is, in principle (not technically, though), same, for both - primitives and objects.
With respect to primitives, the only reason why explicit casting is still needed during narrowing-conversion between compatible types, is because of compiler "wants to make sure", you didn't inadvertently assigned the value of a bigger type, to the variable of smaller type, as this may cause problems. Therefore, you have to explicitly mention that.. announce.. declare out loudly, that YES! you want this narrowing to happen, because you are sure nothing will go wrong, and in that case, compiler "trusts your promise" and compilation is successful. If something will still go wrong, at runtime, that's already not something you did by overlooking types.
On the other hand, the other way around (assigning narrower type to the wider one) is always safe, hence - no explicit casting is needed.
The reason with reference types is identical - Dog
can always be referred as Animal
(assuming Dog extends Animal
), but not every Animal
is guaranteed to be a Dog
. So, you have to be explicit here, as well, because there is a similar chance of committing something wrong.. and by explicit downcast, you "promise to the compiler", that you have examined the code, at least, twice.
So, that's the way javac
compiler is designed. This is an extra layer of safety, Java provides.
Related Topics
Keylistener Not Working for JPAnel
Mapping Postgresql JSON Column to a Hibernate Entity Property
How to Get the Intersection Between Two Arrays as a New Array
Android 6.0 Open Failed: Eacces (Permission Denied)
How to Detect a Loop in a Linked List
How to Open the Default Webbrowser Using Java
Proper Implementation of Cubic Spline Interpolation
How to Run .Jar File by Double Click on Windows 7 64-Bit
Spring MVC: How to Perform Validation
Casting Object Array to Integer Array Error
Make Maven to Copy Dependencies into Target/Lib
Eclipse: How to Build an Executable Jar with External Jar
What HTML Parsing Libraries Do You Recommend in Java