一、用途
C#中有virtual, abstract, new, override四個關鍵字用來管理類別繼承時函數的覆寫關係。二、virtual, abstract, new, override四種關鍵字的比較表
| 關鍵字 | 中文 | 使用類別 | 說明 |
| virtual | 虛擬方法 | 父類別 | 宣告方法且實作,預期子類別會覆寫 |
| abstract | 抽象方法 | 父類別 | 只宣告方法不實作 |
| new | 覆寫方法 | 子類別 | 覆寫父類別宣告的方法 |
| override | 覆寫方法 | 子類別 | 覆寫父類別宣告的方法 |
三、可能的狀況
| 狀況 | 父類別 | 子類別 | 說明 |
| 1 | 無關鍵字 | 無覆寫 | 子類別繼承父類別的方法。 |
| 2 | 無關鍵字 | new | 當子類別要覆寫父類別但父類別沒有關鍵字時,只能以new覆寫,如要使用override,就要將父類別設成virtual。 |
| 3 | virtual | 無覆寫 | 子類別繼承父類別的方法。 |
| 4 | virtual | new | 子類別覆寫父類別方法 |
| 5 | virtual | override | 子類別覆寫父類別方法 |
| 6 | abstract | override | 當父類別有抽象類別時,子類別都必須要用override實作。 |
四、virtual, abstract, new, override的例子
狀況2,如下例class ParentClass{
public void no(){
Console.WriteLine( "I'm parent no class");
}
}
class ChildClass:ParentClass
{
public new void no()
{
Console.WriteLine("I'm Child no class");
}
}
class Program
{
static void Main(string[] args)
{
ParentClass p = new ParentClass();
p.no();
ParentClass c = new ChildClass();
c.no();
}
}
執行結果是:I'm parent no class
I'm Child no class
表示可以在子類別ChildClass中使用new關鍵字來覆寫在父類別無關鍵字的no方法。
狀況4和5,如下例
class ParentClass
{
public virtual void virtualF() {
Console.WriteLine("I'm parent virtual class");
}
public virtual void virtual2F()
{
Console.WriteLine("I'm parent virtual2 class");
}
}
class ChildClass:ParentClass
{
public override void virtualF()
{
Console.WriteLine("I'm Child virtual override class");
}
public new void virtual2F()
{
Console.WriteLine("I'm Child virtual 2 new class");
}
}
class Program
{
static void Main(string[] args)
{
ParentClass p = new ParentClass();
p.virtualF();
p.virtual2F();
ChildClass c = new ChildClass();
ParentClass pc = new ChildClass();
c.virtualF();
c.virtual2F();
pc.virtualF();
pc.virtual2F();
}
}
執行結果是:I'm parent virtual class
I'm parent virtual2 class
I'm Child virtual override class
I'm Child virtual 2 new class
I'm Child virtual override class
I'm parent virtual2 class
首先,物件c和pc都是ChildClass生成,但是pc是作為父類別ParentClass來使用。
virtualF() 使用override:
c.virtualF()和pc.virtualF()都會輸出I'm Child virtual override class
代表無論物件以子類別或父類別來使用,override時,都會採用子類別所定義的方法。
virtual2F() 使用new:
c.virtual2F()會輸出I'm Child virtual 2 new class
pc.virtual2F()會輸出I'm parent virtual2 class
代表物件以子類別來使用時會採用子類別所定義的方法,物件以父類別來使用時會採用父類別所定義的方法。
結論是override把原方法砍掉重練(再也無法使用父類別方法),而new只是定義新方法,但仍會保留原來的方法,要使用父類別方法就宣告成父類別,要使用子類別方法就宣告成子類別。
狀況6,如下例
abstract class AbstractClass
{
public void no()
{
Console.WriteLine("I'm abstract no class");
}
public abstract void abstractF();
}
class childClass2 : AbstractClass
{
public override void abstractF()
{
Console.WriteLine("I'm childClass2 abstract override class");
}
}
class Program
{
static void Main(string[] args)
{
childClass2 c2 = new childClass2();
c2.no();
c2.abstractF();
}
}
執行結果是:I'm abstract no class
I'm childClass2 abstract override class
所謂的abstract method就像例子中的abstractF,只有宣告沒有實作。
如果class中有一個abstract method,class就要設成abstract class,而abstract class 不能直接物件化,必須要有子類別去繼承abstract class並覆寫(override)所有的abstract method。
沒有留言:
張貼留言