I have base class as Animal and child class as Dog
Here is the code:
class Animal
{
public int Legs { get; set; }
public string Name { get; set; }
}
class Dog : Animal
{
public int noOfTail { get; set; }
}
In My Main Method when I execute below I get the exception:
static void Main(string[] args)
{
Animal a = new Animal();
Dog d = new Dog();
d = (Dog)a;
}
but when I first cast my derived class to parent I don't get any exception, and that is why I am confused, can somebody explain reason behind it.
static void Main(string[] args)
{
Animal a = new Animal();
Dog d = new Dog();
a = d;
d = (Dog)a;
}
When we create an instance of a base class, its data members are allocated in memory, but of course data members of inherited classes are not allocated. So, downcasting from a base to a derived class is not possible because data members of the inherited class are not allocated.
Expanding on @ybo's answer - it isn't possible because the instance you have of the base class isn't actually an instance of the derived class. It only knows about the members of the base class, and doesn't know anything about those of the derived class.
Upcasting converts an object of a specialized type to a more general type. Downcasting converts an object from a general type to a more specialized type.
Parent to Child (Explicit casting - Can be successful) Note: Because objects has polymorphic nature, it is possible for a variable of a parent class type to hold a child type. Conclusion : After reading above all, hope it will make sense now like how parent to child conversion is possible(Case 3).
Animal
object cannot be cast to a Dog
type. A Dog
object, on the other hand, can be cast to Dog
type even if you store a Dog
object in a variable of Animal
type.
In your first example you attempt to cast an Animal
to Dog
, which fails, because object is of a wrong class. In your second example you assign a = d
, so now variable a
has type Animal
, but its runtime type is Dog
. That is why the second cast works.
Note: This is only the technical part of your problem, but there is also a logical component to it: your class hierarchy lets you instantiate Animal
class, which is not a leaf class.
A better approach would be to make Animal
an interface or an abstract class. This way you would be able to instantiate only the "actual" animals (Dog
and whatever else you wish to derive from Animal
), while it would not be possible to create an instance of Animal
without saying what kind of animal it represents.
In Case two you have an instance of dog and animal
Animal a = new Animal();
Dog d = new Dog();
Then you have reference copy
of dog to animal
a = d;
So the a is points to d and d is a dog instance and instance properties like noOfTail is still exist but is hidden and not available in object a. and then you have this line :
d = (Dog)a;
In last line you have reference copy of d to a ,so d is point to where a is point to so everything is okay.
but in case one you want copy one Instance of child class
Dog to an instance of Animal so the properties of child class will be lost. you need to confirm that with Compiler and say to him you know instance properties like noOfTail
will not be available any more
your code most be like this :
Animal a = new Animal();
Dog d = new Dog();
d = (a as Dog);
You cannot cast a base class to a derived class, but you can do the opposite: cast a derived class to a base class.
Your second attempt works for a very simple reason: a = d
; => you are assigning a derived class instance to a base class instance.
that OOP fundamental is called polymorphism.
static void Main(string[] args)
{
Animal a = new Animal();
Dog d = new Dog();
a = d; // you can do that but you cant do d=a
d = (Dog)a;
}
To understand it better try to delve into that piece of code:
public void polymorphism()
{
// thats wrong and the compiler will throw an exception (at design time) because animal is not a dog
Dog d = new Animal();
// thats correct becasue dog is an animal
Animal a = new Dog();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With