淺析C# new和override的區別ide
C#中new和override是繼承中常常用到的兩個關鍵字,可是每每有時候容易把這兩個關鍵字的做用搞混淆。函數
new對象
C# new關鍵字表示隱藏,是指加上new關鍵字的屬性或函數將對本類和繼承類隱藏基類的同名屬性或函數繼承
public class A接口
{it
public virtual void Method()class
{方法
Console.WriteLine("This Method in Class A!");總結
}vi
}
public class B : A
{
public new void Method()
{
Console.WriteLine("This Method in Class B!");
}
}
意思也就是 子類使用new 重寫方法後 父類 A=new 子類(); 則站在A的角度調用到的是 A.Method() 而調用不到B.Method(),而當 子類 B=new 子類(); 則調用B.Method(),而調用不到父類A的Method()。(固然 new 和override的子類中均可以用base 調用父類的Method())。 總結通俗的講:new:父類看不到子類的new的新方法,子類看不到父類被new的方法, 而override: 父類和子類看到的都是子類override後的方法。
對於上面這個例子來講,假如運行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函數