理解介面方法和虛方法的區別
第一眼看來,實現介面和覆寫虛方法似乎沒有什麼區別,實際上,實現介面和覆寫虛方法之間的差別很大!!!
派生不能覆寫介面的非虛成員
介面中聲明的成員方法預設情況下並非虛方法,所以,衍生類別不能覆寫基類中實現介面的非虛成員。
看一個例子。
定義介面ITest:
public interface ITest { void Test(); }
實現介面的Base類和Derive類
public class Base:ITest { public Base() { Console.WriteLine("This is base constructor"); } //實現ITest介面 public void Test() { Console.WriteLine("This is in base to ITest implement"); } } public class Derive :Base,ITest { public Derive() { Console.WriteLine("This is derived constructor"); } //測試Derive類實現了ITest嗎?? public void Test() { Console.WriteLine("This is in Derive to ITest implement"); } }
調用對象Base和Derive:
Base b = new Base(); b.Test(); Base d = new Derive();//將d聲明為Base對象 d.Test(); Console.ReadLine();
輸出結果為:
可以看出,b和d執行個體的Test方法實現的行為都是位於基類的!!!這表明了,衍生類別不能覆寫基類中實現介面的成員(非虛方法)
但是,請看下面調用:
Base b = new Base(); b.Test(); Derive d = new Derive(); //將d聲明為Derive對象 d.Test(); Console.ReadLine();
輸出結果為:
因此,如果想要繼承的對象調用介面實現方法,只能聲明為Derive執行個體。這樣做不符合Effective C#中變數都聲明為基執行個體的原則!!!
衍生類別方法個性,將基類方法轉為虛方法
避免這種使用上的混淆,如果確實衍生類別實現方法是個性行為,那麼需要將基類的實現介面的方法前加virtual修飾符!
代碼修改如下:
public class Base:ITest { public Base() { Console.WriteLine("This is base constructor"); } public virtual void Test() //實現ITest介面的虛方法 { Console.WriteLine("This is in base to ITest implemnt"); } } public class Derive :Base,ITest { public Derive() { Console.WriteLine("This is derived constructor"); } public override void Test() //實現介面ITest的複寫方法 { Console.WriteLine("This is in Derive to ITest implemnt"); } }
一次實現,多個關聯對象使用
觀察上面的代碼,我們發現,在基類中實現的介面,如果衍生類別也想實現此介面,那麼它預設繼承了基類的介面實現,所以不用重複寫代碼實現介面。
public interface ITest { void Test(); } public class Base:ITest { public Base() { Console.WriteLine("This is base constructor"); } public void Test() { Console.WriteLine("This is in base to ITest implemnt"); } } public class Derive :Base,ITest { public Derive() { Console.WriteLine("This is derived constructor"); } }
總結:
1、 派生不能覆寫介面的非虛成員;
2、如果衍生類別方法是個性方法,將基類方法轉為虛方法;
3、若基類實現了介面方法,將衍生類別也顯示地繼承此介面,但是不用再次實現了!!!