淺析C# new和override的區別

轉自:https://www.cnblogs.com/OpenCoder/archive/2009/11/20/1607225.html


 

C#中new和override是繼承中經常用到的兩個關鍵字,但是往往有時候容易把這兩個關鍵字的作用搞混淆。

 

  • new

C# new關鍵字表示隱藏,是指加上new關鍵字的屬性或函數將對本類和繼承類隱藏基類的同名屬性或函數

public class A
{
    public virtual void Method()
    {
        Console.WriteLine("This Method in Class A!");
    }
}

public class B : A
{
    public new void Method()
    {
        Console.WriteLine("This Method in Class B!");
    }
}

 

對於上面這個例子來說,假如運行A a=new B();a.Method();會輸出This Method in Class A!,這是因爲class B繼承於class A,現在B中的Method函數隱藏A中的Method,所以從B(包括繼承於B的子類)的角度來看類中的Method就是B.Method,A的Method不可見,但是如果從A的角度來看B,A只認識類B中繼承於類A的Method函數,對於B類中的Method它不可見,所以A a=new B();a.Method();相當於是調用了類B中繼承於A的Method函數

 

  • override

C#中override關鍵字表示重寫,對於加上override關鍵字的屬性或函數將完全覆蓋基類的同名虛屬性或虛函數,使基類的虛屬性和虛函數在整個繼承鏈中都不可見(在子類中用base關鍵字調用除外)。

 

public class A
{
    public virtual void Method()
    {
        Console.WriteLine("This Method in Class A!");
    }
}

public class B : A
{
    public override void Method()
    {
        Console.WriteLine("This Method in Class B!");
    }
}

 

對於上面這個例子來說,假如運行A a=new B();a.Method();會輸出This Method in Class B!,因爲class B的Method函數完全覆蓋基類的同名虛函數Method,使整個繼承鏈中看見的Method函數都是B中的Method,所以就算是以A角度來看B,A看到的Method函數也是B中的Method,因爲A中的Method完全被B的覆蓋了

但是如果要在B的對象中調用A的Method函數還是有辦法,就是使用base關鍵字,比如

 

public class A
{
    public virtual void Method()
    {
        Console.WriteLine("This Method in Class A!");
    }
}

public class B : A
{
    public override void Method()
    {
        base.Method();
    }
}

 

A a=new B();a.Method();會輸出This Method in Class A!,base.Method();表示調用類B中繼承於基類A的Method

 

  • new、override與interface

接口在相互繼承的時候也會隱藏基接口的同名屬性或函數,但是對於接口來說很特殊,隱藏對於基接口來說是不起作用的,接口內部的屬性和函數都只是聲明,它們都指向實現接口的類中的同名實現函數,通過接口調用接口的屬性和函數的時候都會去調用實現類中從上到下最先可見的同名函數和同名屬性:

 

public interface IA
{
    void Method();
}

public interface IB : IA
{
    new void Method();
}

public class IClass:IB
{
    public void Method()
    {
        Console.WriteLine("This Method in Class IClass!");
    }
}

public class ISubClass : IClass
{
    public new void Method()
    {
        Console.WriteLine("This Method in Class ISubClass!");
    }
}

 

IA ia = new ISubClass();ia.Method();輸出This Method in Class IClass!因爲對於ia來說在繼承鏈中最先見到的同名實現函數是類IClass的Method函數

 

把上面的例子稍作修改:

 

public interface IA
{
    void Method();
}

public interface IB : IA
{
    new void Method();
}

public class IClass:IB
{
    public virtual void Method()
    {
        Console.WriteLine("This Method in Class IClass!");
    }
}

public class ISubClass : IClass
{
    public override void Method()
    {
        Console.WriteLine("This Method in Class ISubClass!");
    }
}

 

IA ia = new ISubClass();ia.Method();輸出This Method in Class ISubClass!因爲繼承鏈中的Method函數都被ISubClass的Method覆蓋了,所以對於ia來說在繼承鏈中最先見到的同名實現函數是類ISubClass的Method函數

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章