disclaimer: i am totally newbie to this world of coding! in my course on learning c#, i read this article. https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/knowing-when-to-use-override-and-new-keywords .
code:
public class Car
{
public void DescribeCar()
{
Console.WriteLine("Car: Four wheels and an engine.");
ShowDetails();
}
public virtual void ShowDetails()
{
Console.WriteLine("Car: Standard transportation.");
}
}
public class ConvertibleCar : Car
{
public new void ShowDetails()
{
Console.WriteLine("ConvertibleCar: A roof that opens up.");
}
}
ConvertibleCar myCC = new ConvertibleCar();
myCC.DescribeCar();
myCC.ShowDetails();
//Output
Car: Four wheels and an engine.
Car: Standard transportation.
ConvertibleCar: A roof that opens
Question: i expect with my understanding i should get "ConvertibleCar: A roof than opens" in my second and third line of output. what is it different when calling ShowDetails directly on the derived class, and from within a method in the base class. PS: the showdetials is set at new in the derived class.
Because with new
you effectively shadowed ShowDetails
(in fact, in VB.NET there's a Shadows keyword for this). Moreover, with new
you can make ShadowDetails
a property!
Let's create two classes: Base and Derived:
class Base
{
public virtual int GetInt()
{
return 10;
}
}
class Derived : Base
{
public new int GetInt()
{
return 11;
}
}
Now, let's test them:
Base b;
Derived d;
int x;
b = new Derived();
d = new Derived();
x = b.GetInt(); // x = 10 [Base.GetInt()]
x = d.GetInt(); // x = 11 [Derived.GetInt()]
As you see, although b
is assigned Derived, it still refers to Base
.
But let's do something completely different - let's turn method into a property!
class Derived : Base
{
public new int GetInt
{
get { return 11; }
}
}
Now when we run previous test code we will see that x = 10
:
x = d.GetInt(); // x = 10
But, wait, we don't have GetInt()
method in Derived
class! Why the code is compiled? It's simple - because we shadowed GetInt() method with GetInt
property, now GetInt()
is called from Base
! To confuse things more, the IntelliSense doesn't show GetInt()
method on d
variable, but the compiler is satisfied. To get 11, you need to call property:
x = d.GetInt;
You can also turn GetInt()
method into delegate:
class Derived : Base
{
public new delegate int GetInt();
}
and use it:
Derived.GetInt getIntDelegate = () => 12;
Console.WriteLine(getIntDelegate()); // Prints 12
The new
keyword used for the hiding base member/method. So
public new void ShowDetails()
{
Console.WriteLine("ConvertibleCar: A roof that opens up.");
}
ShowDetails
method is a new
method for ConvertibleCar
class and the base class ShowDetails
method is completely different and it is not in the inheretance chain. Imagine that, you could define the method name like ShowDetails2
in the ConvertibleCar
class. It would be same case.
Also, if you use the override keyword
instead of new
, the ConvertibleCar
class would override the ShowDetails
method.
public class ConvertibleCar : Car
{
public override void ShowDetails()
{
Console.WriteLine("ConvertibleCar: A roof that opens up.");
}
}
And output would be;
Car: Four wheels and an engine.
ConvertibleCar: A roof that opens.
ConvertibleCar: A roof that opens.
To get your expected output, use override
in place of new
:
public override void ShowDetails()
{
Console.WriteLine("ConvertibleCar: A roof that opens up.");
}
If you use new
, you shadowed the ShowDetails
method in the base class. This means that the derived class implementation will only be used when you call the method from a derived class variable.
override
does something different. If ShowDetails
is overridden, then the derived class implementation will always be used as long as the object's underlying type is the derived class, no matter the type of the variable.
This explains why the second line of output is different. The second line is produced from this line:
public void DescribeCar()
{
Console.WriteLine("Car: Four wheels and an engine.");
ShowDetails(); <--------
}
ShowDetails
means this.ShowDetails
. this
is of type Car
but actually refers to an object of ConvertibleCar
. Since ShowDetails
is shadowed, it calls the implementation of Car
(because this
is of type Car
!)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.