2014年8月16日 星期六

C# - About Multiple Inheritance 關於多重繼承

物件導向程式語言中的多重繼承(Multiple Inheritance, MI)指的是一個類別可以同時從多於一個父類繼承行為與特徵的功能。與單一繼承相對,單一繼承指一個類別只可以繼承自一個父類。在Java和C++都支援了這樣的特性,但在C#裡這樣的特性,微軟用另外的方法去演譯它。

如何才能在C#中實現多重繼承,其實這是一個很有趣的問題。因為C++支援多重繼承,允許對現實世界進行更直接的建模,Borland C++的OWL Framework大量使用多重繼承來描述視窗的關係。微軟的MFC僅使用單一繼承描述視窗,ATL使用多重繼承實現COM/ActiveX,WTL則使用多重繼承實現視窗。但是在C#中是沒有類的多重繼承這個概念.要使用多重繼承必須要通過介面Interface來完成。可是Interface實際上就是一個虛函數清單指標,內部封裝的只有函數和屬性,而且介面(Interface)因為沒有建構函數,不能實體化只能通過繼承才可以使用,這一點和抽象類別很類似,可是抽象類別本身就是個類別,有方法的實現,它所描述的物件是一個無法在現實中具現的物件。以下例子如何在C#中實現多重繼承。

namespace Intdv
{
    public abstract class myBase
    {
        public myBase()
        {
        }
    }
}

namespace Intdv
{
    class myDerive1 : Intdv.myBase
    {
        string myName;

        public myDerive1()
        {
            myName = "yarshary";
        }

        public void ShowMyName()
        {
            Console.WriteLine("my name is: " + this.myName);
        }

        public void reName(string n)
        {
            myName = n;
        }
    }

    public interface ImyDerive1
    {
        void ShowMyName();
        void reName(string n);
    }
}

namespace Intdv
{
    public class myDerive2 : Intdv.myBase
    {
        int MyAge;

        public myDerive2()
        {
            MyAge = 21;
        }

        public void ShowMyAge()
        {
            Console.WriteLine("my age is:" + MyAge);
        }

        public void reAge(int a)
        {
            this.MyAge = a;
        }

    }

    public interface ImyDerive2
    {
        void ShowMyAge();

        void reAge(int a);
    }
}

namespace Intdv
{
    public sealed class myMDerive : Intdv.myBase, Intdv.ImyDerive1, Intdv.ImyDerive2
    {
        Intdv.myDerive1 d1;
        Intdv.myDerive2 d2;

        public myMDerive()
        {
            d1 = new myDerive1();
            d2 = new myDerive2();
        }

        public void ShowMyName()
        {
            d1.ShowMyName();
        }

        public void reName(string n)
        {
            d1.reName(n);
        }


        public void ShowMyAge()
        {
            d2.ShowMyAge();
        }

        public void reAge(int a)
        {
            d2.reAge(a);
        }
    }

}

在一開始定義了一個基底類別myBase,並繼承兩個介面為myDerive1,myDerive2
這兩個介面分別定義了一組操作,myDerive1中定義了操作ShowMyName 和 reName 並通過接ImyDerive1加以描述。myDerive2中定義了操作ShowMyAge 和 reAge 並通過介面ImyDerive2來描述。這樣多重繼承中只用繼承介面也就是ImyDerive1和ImyDerive2就可以保證操作列表的繼承,操作的實現通過組合模型。在介面方法中實作繼承介面myMDerive,雖然只繼承了介面,
可是在建構函數中,卻動態分配(New)了myDerive1 和 myDerive2 兩個對象,並在操作ShowMyName 等介面繼承來的操作中實際調用了myDerive1 和 myDerive2 的操作。由於myDerive1 和 myDerive2 是在myMDerive內定義的,所以用戶端代碼並不需要管理物件的分配和釋放。

-雲遊山水為知已逍遙一生而忘齡- 電腦神手