I have the following code.
public class Parent
{
public void Print()
{
Console.WriteLine ("Parent Method");
}
}
public class Child : Parent
{
public new void Print()
{
Console.WriteLine ("Child Method");
}
}
public class Program
{
public static void Main()
{
Child C = new Child();
C.Print();
}
}
If I run this code, I get the result "Child Method" But if I do the following, why do I get the result "Parent Method"?
public class Parent
{
public void Print()
{
Console.WriteLine ("Parent Method");
}
}
public class Child : Parent
{
public new void Print()
{
Console.WriteLine ("Child Method");
}
}
public class Program
{
public static void Main()
{
Parent P = new Child(); // The only difference is this.
P.Print();
}
}
The only difference is as below
Child C = new Child();
Parent P = new Child();
I thought new Child()
means that we create the instance of Child
class.
And I thought both, C
and P
, are just object reference variables that hold the location of instance of Child
class.
Can you correct me if I'm wrong or tell me if I miss something because I don't understand why in the above cases I get different results?
We can assign child class object to parent class reference variable but we can't assign parent class object to child class reference variable.
The parent class can hold reference to both the parent and child objects. If a parent class variable holds reference of the child class, and the value is present in both the classes, in general, the reference belongs to the parent class variable.
Answer: (c) Dynamic method dispatch. Q65. When reference variable of Parent class refers to the object of Child class, then it is known as. (a) Side casting.
In Java, the reference variable of the Parent class is capable to hold its object reference as well as its child object reference.
It's because you've redeclared the Print
method in Child
. So at compile time, P.Print()
resolves to Parent.Print
, but C.Print()
resolves to Child.Print()
. If you had a virtual method which was overridden in Child
instead, they'd both print "Child Method":
public class Parent
{
// Declare this as virtual, allowing it to be overridden in
// derived classes. The implementation will depend on the
// execution-time type of the object it's called on.
public virtual void Print()
{
Console.WriteLine ("Parent Method");
}
}
public class Child : Parent
{
// Override Parent.Print, so if Print is called on a reference
// with compile-time type of Parent, but at execution it
// refers to a Child, this implementation will be executed.
public override void Print()
{
Console.WriteLine ("Child Method");
}
}
Related:
override
and new
? (C# FAQ entry on MSDN - turns out to have been written by me, but I'd forgotten!)override
and new
keywords (MSDN)Here is what happens under the hood
Child C = new Child();
C.Print();
Because you are hiding methods, not overriding them. so Print method in Parent is hidden and Child.Print() is invoked.
Parent P = new Child(); // The only difference is this.
P.Print();
This (New Child()) will be called on a Parent type Reference.
if you try this one, Parent type reference will be casted to Child type. Henceforth Child.Print() is invoked.
Parent P = new Child();
((Child)P).Print();
output will be: Child Method
Since the Print
method is not virtual
, the compiler will not emit code to tell the CLR to invoke the method according to the actual runtime type.
So, when your variable is referred as Child
, Child.Print
would be invoked. But, when you're referring to it as Parent
, Parent.Print
would be used.
The use of the new
keyword here is only meant for shadowing, to tell the compiler that the child method is indeed hiding the parent method and not overriding it, but has no effect otherwise.
JCronin, you are casting to the Parent with Parent P = new Child(). To get the Child class behavior, you have to either cast it back to a Child (var x = (Child)P) or create the Child instance instance (Child P = new Child()).
See Downcasting
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