[英]Concept of C# polymorphism
下面的代碼:
public class Program
{
static void Main(string[] args)
{
father f = new son(); Console.WriteLine(f.GetType());
f.show();
}
}
public class father
{
virtual public void show()
{
Console.WriteLine("father");
}
}
public class son : father
{
public override void show()
{
Console.WriteLine("son");
}
}
結果是“兒子”。
如果我將“ public override void show()
”修改為“ public new void show()
”,則結果為“父親”。
因此,我總結出以下“規則”:
以上是我對多態性的理解,是否有誤解和錯誤?
使用'new'修飾符,將在編譯時確定要調用的函數。程序將選擇對象的聲明類型來調用其函數。(如上所述,f的聲明類型為父親,因此使用'new'修飾符使輸出以顯示“父親”。
並不是的。 這一決定仍然在執行時做,但new
方法不會覆蓋在基類中的虛方法。 通過稍微擴展示例,可以很容易地看出這一點:
using System;
class Base
{
public virtual void Foo()
{
Console.WriteLine("Base.Foo");
}
}
class Derived : Base
{
public override void Foo()
{
Console.WriteLine("Derived.Foo");
}
}
class MoreDerived : Derived
{
public new void Foo()
{
Console.WriteLine("MoreDerived.Foo");
}
}
class Test
{
static void Main()
{
Base x = new MoreDerived();
x.Foo(); // Prints Derived.Foo
}
}
在這里,在編譯時決定調用Base.Foo
的最重要的實現-例如,如果有多個Foo
簽名,則將決定使用哪個簽名。 當然,目前尚不知道哪個實現是“最重要的”。
在執行時 ,CLR將根據目標對象的實際類型( MoreDerived
找到最被重寫的實現。 但是MoreDerived.Foo
不會覆蓋Base.Foo
...,而Derived.Foo
可以,因此Derived
的實現是實際執行的。
是的,它的工作原理是……您的理解是正確的。
但是對於第二種情況,當您使用override
new
索引時,它將隱藏實際的實現,即父類實現
由於使用new關鍵字定義此方法,因此不調用派生類方法-而是調用基類方法。
來自MSDN的示例
// Define the base class
class Car
{
public virtual void DescribeCar()
{
System.Console.WriteLine("Four wheels and an engine.");
}
}
// Define the derived classes
class ConvertibleCar : Car
{
public new virtual void DescribeCar()
{
base.DescribeCar();
System.Console.WriteLine("A roof that opens up.");
}
}
class Minivan : Car
{
public override void DescribeCar()
{
base.DescribeCar();
System.Console.WriteLine("Carries seven people.");
}
}
上課
Car[] cars = new Car[3];
cars[0] = new Car();
cars[1] = new ConvertibleCar();
cars[2] = new Minivan();
輸出
Car object: YourApplication.Car
Four wheels and an engine.
----------
Car object: YourApplication.ConvertibleCar
Four wheels and an engine.
----------
Car object: YourApplication.Minivan
Four wheels and an engine.
Carries seven people.
----------
MSDN就是一個很好的例子: 知道何時使用覆蓋和新關鍵字(C#編程指南)
使用'new'修飾符,將在編譯時確定要調用的函數。程序將選擇對象的聲明類型來調用其函數。(如上所述,f的聲明類型為父親,因此使用'new'修飾符使輸出以顯示“父親”。
這有點不對。 使用new
表示此函數不會覆蓋基類的任何函數。 函數分派仍然在運行時發生,但是不考慮該函數。 如果您有“孫子”或“女兒”課程來測試更多內容,則區別會更加明顯。
通過類的類型調用普通方法,通過分配給對象的內存內容調用虛擬方法。 現在,關鍵字new
隱藏了多態的概念,只關心其類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.