首頁  >  文章  >  後端開發  >  C#設計模式-衍生類別實作非虛擬介面陷阱的實例程式碼分享

C#設計模式-衍生類別實作非虛擬介面陷阱的實例程式碼分享

黄舟
黄舟原創
2017-03-18 13:23:431392瀏覽

理解介面方法和虛擬方法的區別

  第一眼看來,實作介面和覆寫虛方法似乎沒有什麼差別,實際上,實作介面和覆寫虛方法之間的差別很大! ! !

派生無法覆寫介面的非虛成員

  介面中宣告的成員方法預設並非虛方法,所以,衍生類別不能覆寫基底類別中實作介面的非虛成員
看一個例子。
定義介面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();

輸出結果為:


C#設計模式-衍生類別實作非虛擬介面陷阱的實例程式碼分享

  可以看出,b和d實例的Test方法實作的行為都是位於基底類別的! ! !這顯示了,衍生類別不能覆寫基底類別中實作介面的成員(非虛擬方法)

但是,請看下面呼叫:

            Base b = new Base();
            b.Test();
            Derive d = new Derive(); //将d声明为Derive对象
            d.Test();
            Console.ReadLine();

輸出結果為:


C#設計模式-衍生類別實作非虛擬介面陷阱的實例程式碼分享

因此,如果想要繼承的物件呼叫介面實作方法,只能宣告為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 、若基類別實作了接口方法,將衍生類別也顯示地繼承此接口,但是不用再實作了! ! !

以上是C#設計模式-衍生類別實作非虛擬介面陷阱的實例程式碼分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn