在繼承和多型中的記憶體分配機制

fan_rockrock發表於2014-04-12

在繼承和多型中的記憶體分配機制:

 繼承、封裝和多型是物件導向的三大支柱要素,也是C#語言中最為重要的概念。在這裡無意具體講解他們的意義、使用方法等,只是想通過具體例項,從它們的記憶體分配,以期理解其執行機制,從而對繼承和多型概念有深層次的理解。 這裡節選Anytao的《你必須知道的.NET》之繼承本質論中示例程式碼和演示圖片,加以說明:

 public abstract class Animal

    {

        public abstract void ShowType();

        public void Eat()

        {

            Console.WriteLine("Animal always eat.");

        }

    }

    public class Bird: Animal

    {

        private string type = "Bird";

        public override void ShowType()

        {

            Console.WriteLine("Type is {0}", type);

        }

        private string color;

        public string Color

        {

            get { return color; }

            set { color = value; }

        }

    }

    public class Chicken : Bird

    {

        private string type = "Chicken";

        public override void ShowType()

        {

            Console.WriteLine("Type is {0}", type);

        }

        public void ShowColor()

        {

            Console.WriteLine("Color is {0}", Color);

        }

    }

執行:

 public class TestInheritance

    {

        public static void Main()

        {

            Bird bird = new Bird();

            Chicken chicken = new Chicken();

        }

    }



從繼承的方面: 

我們可以得出如下結論:

1.即使是對同名的private型別欄位type,當在子類中依然定義時,則在子類物件的欄位中依然存在。而父類和其卻將type欄位都加上了Bird_type和Chicken_type加以區分;

2.Chicken方法表中,可以實現ShowColor方法,其依賴於屬性Color。其是可以繼承的,因為就其本質,它等價於在C++中的Get和Set函式(這裡屬性,包含get和set訪問器);

 

然而從多型的方面: 

  Bird bird2 = new Chicken();

然而如果使用這個語句,如果呼叫bird2.ShowType(),將會產生什麼結果呢?

答案是:"Type is Chicken"; 

這就是多型的魅力!在這裡它如何實現的呢?我們詳細講述一下它的實現方法:

1.對於Bird型別引用,他先查閱自己的Method Table 表,檢測定位到標記為Virtual的方法或已經是Override的方法,然後從所指向具體的例項的TypeHandler指向的Method Table 中,查閱是否有被標記為override的對應函式,如果有則呼叫;如果沒有,則向上一直追溯至System.Object(例如Object自帶的幾個方法Tostring()、Equals()等)為止;

2.Override的實現機理就是將子類的同名函式,覆蓋掉父類的函式(因為:在初始化Chicken的方法表時是要按父類優先,子類最後的原則的,這樣才能夠實現"覆蓋").然而預期相對應的New關鍵字(或預設不寫時) 。它所做的,就是在子類中另寫一個同名方法,用型別來標記(雷同於前述的欄位同名情況)。這樣同樣是用上述呼叫語句,當父類檢測自己的標記為Virtual的方法或已經是Override的方法,然後從所指向具體的例項的TypeHandler指向的Method Table 中,查閱是否有被標記為override的對應函式,如果有,並且,還存在同名的子型別標記的同名函式,則呼叫標記為本類(父類)的函式,從而沒有實現覆蓋;如果沒有,則向上一直追溯至System.Object(例如Object自帶的幾個 方法Tostring()、Equals()等)為止;

 

  綜述之,實現繼承和多型的記憶體分配機制的差距,以及具體的用Virtual和Override關鍵字的函式實現覆蓋過載 ,讓我們看到記憶體在其中起到的巨大作用,頁可以加深對繼承和多型——物件導向中最重要的概念的理解


相關文章