最近正在 看你必須知道的.NET這本書,下面是在看書過程中,記載的自己的一些感受和書中沒有看到的,記下來供自己以後翻看:
07-10
page23 1.2章節 繼承
ok,首先我們需要有對象定義,也就是class定義,根據書中的例子我們寫出下面3個類的代碼
public abstract class Animal
{
public abstract void ShowType();
public void Eat()
{
Console.WriteLine("Animal always eat!");
}
}
public class Bird:Animal
{
private string color;
public string Color
{
get { return color; }
set { color = value; }
}
private string type = "Bird";
public string Type
{
get { return type; }
}
public override void ShowType()
{
Console.WriteLine("Type is {0}", type);
}
}
public class Chicken:Bird
{
private string type = "Chicken";
public new string Type
{
get { return type; }
}
public override void ShowType()
{
Console.WriteLine("Type is {0}", type);
}
public void ShowColor()
{
Console.WriteLine("Color is {0}", Color);
}
}
當我們隻是聲明一個對象變量的時候:Bird bird ;僅僅是一個引用(指針),儲存線上程的堆棧上,占用4Byte的記憶體空間,将用于儲存Bird對象的有效位址,此時bird未指向任何有效的執行個體。
建立新對象 bird=new Bird();要說的主要在這裡,通過F11進入Bird類内部會發現,程式對類内部的字段初始化,然後執行構造函數,這裡private string color;隻是聲明變量沒有指派 ,設定斷點不會執行到該語句,如果private string color = string.Empty;就會執行到這裡
然後是書中重點提到的内容:
聲明并建立兩個對象:Bird bird2 = new Chicken();
Chicken chicken = new Chicken();
這時候bird2的字段或者屬性讀取的是Bird類的值,而方法是執行的Chicken的方法
書中的解釋是:bird2對象和chicken對象在記憶體布局上是一樣的,差别在于其引用指針的類型不同:brid2為Bird類型指針,而chicken為Chicken類型指針。以方法調用為例,不同的類型指針在虛拟方法表中有不同的附加資訊作為标志來差別其通路的位址區域,稱為offset。不用類型的指針隻能在其特定的位址區域内執行,子類覆寫父類時會保證其通路位址區域的一緻性,進而解決了不同的類型通路具有不同的通路權限問題。
執行就近原則:對于同名字段或者方法,編譯器是按照其順序查找來引用的,首先通路離他最近的字段或者方法,如上Type,這也就是為什麼在對象建立時必須将字段按順序排列,而父類要先于子類編譯的原因了。
轉載于:https://www.cnblogs.com/yinmz/archive/2009/07/10/1520677.html