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 ClassCastException
s:
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
}
downcast and upcast
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.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!
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
}
Upcasting/Downcasting in Java
With the implicit upcast at this line:
Animal myAnimal = myDog;
You are not doing anything to change the underlying instance myDog
. What you are doing is assigning it to a variable of a type one level higher in the inheritance tree. Effectively, this restricts which methods can be called to only those defined in Animal
, but does not change how those methods resolve.
Because you have restricted the methods available to only those defined on the parent class Animal
, the compiler cannot resolve Dog#bark()
, since it is a method of Dog
, and the variable myAnimal
is defined to be of type Animal
which has no #bark
method.
#move()
is a method of both Animal
and Dog
, so it resolves, but it resolves to the method defined on Dog
, since myAnimal
still refers to an instance of Dog
, despite being upcast.
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
Related Topics
Generate 16-Bit Grayscale Bitmapdata and Save to File
Jquery Ajax Call to an ASP.NET Webmethod
How to Write the Escape Char '\' to Code
Does C# Support Project-Wide Default Namespace Imports Like Vb.Net
Datagridview Using Sortablebindinglist
Finding a Subsequence in Longer Sequence
Caliburn.Micro Serialization Issue When Implementing Propertychangedbase
JSON.Net Serialize Directly from Oledbconnection
Easier Way of Writing Null or Empty
Case Statement Block Level Declaration Space in C#
Regex Split String But Keep Separators
Filesystemwatcher Fails to Access Network Drive
C# Random Numbers Aren't Being "Random"
What Is the Meaning of Thread-Agility in ASP.NET