Differencebetween Up-Casting and Down-Casting with Respect to Class Variable

What is the difference between up-casting and down-casting with respect to class variable

Upcasting is casting to a supertype, while downcasting is casting to a subtype. Upcasting is always allowed, but downcasting involves a type check and can throw a ClassCastException.

In your case, a cast from a Dog to an Animal is an upcast, because a Dog is-a Animal. In general, you can upcast whenever there is an is-a relationship between two classes.

Downcasting would be something like this:

Animal animal = new Dog();
Dog castedDog = (Dog) animal;

Basically what you're doing is telling the compiler that you know what the runtime type of the object really is. The compiler will allow the conversion, but will still insert a runtime sanity check to make sure that the conversion makes sense. In this case, the cast is possible because at runtime animal is actually a Dog even though the static type of animal is Animal.

However, if you were to do this:

Animal animal = new Animal();
Dog notADog = (Dog) animal;

You'd get a ClassCastException. The reason why is because animal's runtime type is Animal, and so when you tell the runtime to perform the cast it sees that animal isn't really a Dog and so throws a ClassCastException.

To call a superclass's method you can do super.method() or by performing the upcast.

To call a subclass's method you have to do a downcast. As shown above, you normally risk a ClassCastException by doing this; however, you can use the instanceof operator to check the runtime type of the object before performing the cast, which allows you to prevent ClassCastExceptions:

Animal animal = getAnimal(); // Maybe a Dog? Maybe a Cat? Maybe an Animal?
if (animal instanceof Dog) {
// Guaranteed to succeed, barring classloader shenanigans
Dog castedDog = (Dog) animal;
}

Downcasts can be expressed more succinctly starting from Java 16, which introduced pattern matching for instanceof:

Animal animal = getAnimal(); // Maybe a Dog? Maybe a Cat? Maybe an Animal?
if (animal instanceof Dog castedDog) {
// now castedDog is available here as in the example above
}

What are the reasons upcasting and downcasting are used in C++?

When have a base class, from which several classes inherit, we often want a pointer that can point to one of those derived classes.

For example we can have an Animal class and derived Dog and Cat classes:

class Animal {};

class Dog : public Animal {};
class Cat : public Animal {};

Dog dog;
Animal* a = &dog;

Cat cat;
Animal* b = &cat;

Often times, we want to have a pointer that can pointer to one of these objects. We can use an Animal pointer, since both a Dog and a Cat are a type of Animal. This is the nature of upcast. We upcast a derived class and represent it as the base class.

What about downcasting? We can do so using a dynamic_cast:

Cat c;
Animal* animal = &c; //Implicit upcast
Cat* cat = dynamic_cast<Cat*>(animal); //Explicit downcast
//Check if dynamic cast worked:
if(!cat) {
//ERROR: Not a cat object
}

What is up cast and down cast in inheritence?

This is upcasting.

Upcasting is basically “widening” or casting up the tree, (parents), while downcasting is “narrowing” or specialization, casting down the tree (children)

Or you can say upcasting is derived -> base type.
Downcasting is base -> derived type.

For example

Animal * a = new Dog();

is upcasting,

whereas

(Dog *) a 

is downcasting (since a was defined as Animal *)

What is the purpose of downcasting and upcasting at the same time?

Does Dog inherit from Animal? I will assume yes.

To answer the question - There is no point to do that. It can be simplified such as:

Dog dog = new Dog();
Animal animal1 = dog;
Animal animal2 = dog;

You may want to downcast when the variables (animal1 or animal2) are from type Dog and you have an object from another type that Dog inherits from (e.g. Animal) - but be sure that that object really is Dog.

Upcasting Downcasting

It's giving you an error because a isn't an instance of C - so you're not allowed to downcast it. Imagine if this were allowed - you could do:

Object o = new Object();
FileInputStream fis = (FileInputStream) o;

What would you expect to happen when you tried to read from the stream? What file would you expect it to be reading from?

Now for the second part:

A a=new A();
C c=new C();
C c=(C)a;

That will not work fine - for a start it won't even compile as you're declaring the same variable (c) twice; if you fix that mistake you'll still get an exception when you try to cast an instance of A to C.

This code, however, is genuinely valid:

A a = new C(); // Actually creates an instance of C
C c = (C) a; // Checks that a refers to an instance of C - it does, so it's fine

Why is upcasting a Class not changing overridden methods?

Please have a look at this question for more understanding of upcast and downcast:

What is the difference between up-casting and down-casting with respect to class variable

I also made an example for looking at upcast behavior:

abstract class Animal 
{
public void saySomething()
{
System.out.println("Some Animal sound");
}

public abstract void getTheBall();
}

class Horse extends Animal
{
public void saySomething()
{
System.out.println("Neigh Neigh");
}

public void getTheBall()
{
System.out.println("I won't, Try a dog, I am a Horse!");
}
}

class Dog extends Animal
{
public void saySomething()
{
System.out.println("woof woof, waon waon");
}

public void getTheBall()
{
System.out.println("huf huf, here it is!");
}
}

public class Main
{
public static void main (String [] args)
{
Dog dog = new Dog();
Horse horse = new Horse();
Animal animal = dog;
Animal horseAnimal = new Horse();

//upcasting
Dog upcastedAnimal = upcastToDog(animal);
dog.saySomething();
dog.getTheBall();

upcastedAnimal.saySomething();
upcastedAnimal.getTheBall();

horse.saySomething();
horse.getTheBall();

try {
Dog upcastedDog = upcastToDog(horseAnimal);
} catch (Exception ex){
System.out.println(ex.getClass().getSimpleName() + ": Obviously a horse is not a dog!");
}
}

public static Dog upcastToDog(Animal animal){
return (Dog) animal;
}
}

Output:

woof woof, waon waon
huf huf, here it is!
woof woof, waon waon
huf huf, here it is!
Neigh Neigh
I won't, Try a dog, I am a Horse!
ClassCastException: Obviously a horse is not a dog!

First of all java will throw exception if incompatible types are trying to be casted.

In the case when cast is possible, overriden methods will always be called from the actual instance. In your case instance is ScottishPerson so methods will be called on ScottishPerson, even if you hold its reference in a BritishPerson.

you can run the example here https://repl.it/B83f/3

In JLS it is covered here "Narrowing Reference Conversion", as he name suggests only reference is narrowed or widened (or upcasted or downcasted) not the instance.

downcast and upcast

  1. That is correct. When you do that you are casting it it into an employee object, so that means you cannot access anything manager specific.

  2. Downcasting is where you take a base class and then try and turn it into a more specific class. This can be accomplished with using is and an explicit cast like this:

    if (employee is Manager)
    {
    Manager m = (Manager)employee;
    //do something with it
    }

or with the as operator like this:

Manager m = (employee as Manager);
if (m != null)
{
//do something with it
}

If anything is unclear I'll be happy to correct it!



Related Topics



Leave a reply



Submit