Explicit Casting from Super Class to Subclass

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 a Sub as parameter.

  • implement a factory of Super and have a method that takes a Sub 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



Leave a reply



Submit