C#中virtual,abstract,override用于方法重載,子類覆寫了父類的相同方法,父類中的實作不可能再被外面調用。
new的作用是投影(shadowing),子類隐藏了父類的相同方法,通過強制類型轉換外面還可以調用父類的實作。
下面是重載的例子
Code:
點選(此處)折疊或打開
class Parent
{
public virtual Parent foo()
{
System.Console.WriteLine("Parent.foo()");
return this;
}
}
class Child : Parent
public override Parent foo()
System.Console.WriteLine("Child.foo()");
Test:
class Program
static void Main(string[] args)
Child c =new Child();
c.foo();
((Parent)c).foo();
Result:
Child.foo()
下面是投影的例子
public Parent foo()
public new Child foo()
Parent.foo()
重載的規則:
父類提供實作,則父類使用virtual關鍵字
父類不提供實作,則父類自身和相關方法使用abstract關鍵字,此時子類必須提供實作
子類重載需使用override關鍵字,如省略當作new(即投影)處理,并且編譯器報編譯警告
重載時子類方法不能改寫傳回值類型
子類中可以使用base關鍵字引用父類的實作
投影的規則:
父類必須提供實作(甚至可以有virtual關鍵字)
子類應該使用new關鍵字,如省略也當作new處理,但編譯器報編譯警告
投影時子類方法可以改寫傳回值類型
除此以外還有一種接口投影的情況,通過接口投影可以新定義一個和接口定義同名同參但不同傳回類型的函數。
比如:
interface MyInterface
Object foo();
class MyImp : MyInterface
Object MyInterface.foo()
System.Console.WriteLine("MyInterface.foo()");
return null;
public MyImp foo()
System.Console.WriteLine("foo()");
MyImp myImp = new MyImp();
myImp.foo();
((MyInterface)myImp).foo();
foo()
MyInterface.foo()