[英]c#: flow of control when calling an inherited base method, which inturn calls a base virtual method which is set as new in derived class
免责声明:我是这个编码世界的新手! 在学习C#的课程中,我阅读了这篇文章。 https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/classes-and-structs/knowing-when-to-use-override-and-new-keywords 。
码:
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
问题:我希望凭自己的理解,我应该在第二行和第三行输出中看到“ ConvertibleCar:屋顶比开口”。 直接在派生类上以及从基类的方法内部调用ShowDetails时有什么不同。 PS:showdetials在派生类中设置为new。
因为有了new
您就可以有效地遮盖ShowDetails
(实际上,在VB.NET中,有一个Shadows关键字用于此功能)。 此外,使用new
可以使ShadowDetails
成为属性!
让我们创建两个类:Base和Derived:
class Base
{
public virtual int GetInt()
{
return 10;
}
}
class Derived : Base
{
public new int GetInt()
{
return 11;
}
}
现在,让我们对其进行测试:
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()]
如您所见,尽管b
被分配了Derived,但它仍然指向Base
。
但是,让我们做一些完全不同的事情-让我们将方法变成属性!
class Derived : Base
{
public new int GetInt
{
get { return 11; }
}
}
现在,当我们运行之前的测试代码时,我们将看到x = 10
:
x = d.GetInt(); // x = 10
但是,等等, Derived
类中没有GetInt()
方法! 为什么要编译代码? 很简单-因为我们用GetInt
属性遮盖了GetInt()方法, GetInt
现在可以从Base
调用GetInt()
! 更GetInt()
困惑的是,IntelliSense并未在d
变量上显示GetInt()
方法,但是编译器很满意。 要获得11,您需要调用属性:
x = d.GetInt;
您还可以将GetInt()
方法转换为委托:
class Derived : Base
{
public new delegate int GetInt();
}
并使用它:
Derived.GetInt getIntDelegate = () => 12;
Console.WriteLine(getIntDelegate()); // Prints 12
用于隐藏基本成员/方法的new
关键字。 所以
public new void ShowDetails()
{
Console.WriteLine("ConvertibleCar: A roof that opens up.");
}
ShowDetails
方法是ConvertibleCar
类的new
方法,基类ShowDetails
方法是完全不同的,并且不在继承链中。 想象一下,您可以在ConvertibleCar
类中定义类似ShowDetails2
的方法名称。 情况会一样。
另外,如果使用override keyword
而不是new
, ConvertibleCar
类将覆盖ShowDetails
方法。
public class ConvertibleCar : Car
{
public override void ShowDetails()
{
Console.WriteLine("ConvertibleCar: A roof that opens up.");
}
}
输出将是;
Car: Four wheels and an engine.
ConvertibleCar: A roof that opens.
ConvertibleCar: A roof that opens.
要获得预期的输出,请使用override
代替new
:
public override void ShowDetails()
{
Console.WriteLine("ConvertibleCar: A roof that opens up.");
}
如果使用new
,你遮挡的ShowDetails
在基类的方法。 这意味着仅当您从派生类变量调用方法时,才使用派生类实现。
override
功能有所不同。 如果ShowDetails
被覆盖,则无论变量的类型如何,只要对象的基础类型是派生类,就将始终使用派生类实现。
这解释了为什么第二行输出不同。 第二行是从此行产生的:
public void DescribeCar()
{
Console.WriteLine("Car: Four wheels and an engine.");
ShowDetails(); <--------
}
ShowDetails
表示this.ShowDetails
。 this
是Car
类型,但实际上是指ConvertibleCar
的对象。 由于ShowDetails
处于阴影中,因此它将调用Car
的实现(因为this
是Car
类型!)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.