[英]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.