標籤:
今天工作不是很忙,使得有些空閑時間,看了下以前的學習筆記,又看到C#繼承這一塊的內容,雖然早就知道C#中的繼承是可以繼承私人成員的,但卻一直沒有深入剖析其中的原理,今天就深入的研究了一下。
首先採用反射的方式來擷取,但是一點結果都沒有,然後查了一些資料,瞭解到VMT(虛擬方法表)的概念,這裡也不做陳述,改裝了一個別人的例子來查看:
using System;class Base{ private int flag = 1; public int GetNum(Child c) { return c.flag; } public int GetNum(Base b) { return b.flag; } public Base() { } public Base(int flag) { this.flag = flag; }}class Child : Base{ private int flag = 2; public new int GetNum(Child c) { return c.flag; } public Child(int flag) : base(flag) { this.flag = 3; }}class test{ public static void Main() { Base b = new Base(); Child c = new Child(4); Console.WriteLine(b.GetNum(c)); Console.WriteLine(c.GetNum(c)); Console.WriteLine(b.GetNum((Base)c)); }}
這裡的運行結果是4,3,4.
為什麼會是這樣呢,可以分析一下:
Main函數中
Base b = new Base();
Child c = new Child(4);
這兩句話執行後 b,c的記憶體結構不做陳述了,
Console.WriteLine(b.GetNum(c));
執行時會調用Base類的GetNum(Child c)的重載,此時Base類不能擷取到Chlid的私人變數,所以輸出Child在父類中繼承的flag值為4(建構函式中base(flag)改為4的),此時已經可以證明私人欄位被子類繼承了。
執行
Console.WriteLine(c.GetNum(c));
得到結果3,這裡的就需要不分析了
執行
Console.WriteLine(b.GetNum((Base)c));
得到4也充分證明了私人欄位被子類繼承了。
這裡也可以監視一下c的地址,看一下整個輸出過程是不是同一個對象:
C#對私人成員的繼承