繼承。建構函式呼叫序列
考慮我們有一個類 Animal
,它有一個子類 Dog
class Animal
{
public Animal()
{
Console.WriteLine("In Animal's constructor");
}
}
class Dog : Animal
{
public Dog()
{
Console.WriteLine("In Dog's constructor");
}
}
預設情況下,每個類都隱式繼承 Object
類。
這與上面的程式碼相同。
class Animal : Object
{
public Animal()
{
Console.WriteLine("In Animal's constructor");
}
}
在建立 Dog
類的例項時,如果沒有對父類中的另一個建構函式進行顯式呼叫,則將呼叫基類的預設建構函式(不帶引數) 。在我們的例子中,首先將被稱為 Object's
建構函式,然後是 Animal's
,最後是 Dog's
建構函式。
public class Program
{
public static void Main()
{
Dog dog = new Dog();
}
}
輸出將是
在 Animal 的建構函式中,
在 Dog 的建構函式中
顯式呼叫 parent 的建構函式
在上面的例子中,我們的 Dog
類建構函式呼叫了 Animal
類的預設建構函式。如果需要,可以指定應該呼叫哪個建構函式:可以呼叫父類中定義的任何建構函式。
考慮一下我們有這兩個類。
class Animal
{
protected string name;
public Animal()
{
Console.WriteLine("Animal's default constructor");
}
public Animal(string name)
{
this.name = name;
Console.WriteLine("Animal's constructor with 1 parameter");
Console.WriteLine(this.name);
}
}
class Dog : Animal
{
public Dog() : base()
{
Console.WriteLine("Dog's default constructor");
}
public Dog(string name) : base(name)
{
Console.WriteLine("Dog's constructor with 1 parameter");
Console.WriteLine(this.name);
}
}
這是怎麼回事?
我們在每個類中有 2 個建構函式。
base
是什麼意思?
base
是對父類的引用。在我們的例子中,當我們像這樣建立一個 Dog
類的例項時
Dog dog = new Dog();
執行時首先呼叫 Dog()
,它是無引數建構函式。但它的身體不能立即起作用。在建構函式的括號之後,我們有一個這樣的呼叫:base()
,這意味著當我們呼叫預設的 Dog
建構函式時,它將依次呼叫父代的預設建構函式。在父項的建構函式執行之後,它將返回,然後最後執行 Dog()
建構函式體。
所以輸出將是這樣的:
Animal 的預設建構函式
Dog 的預設建構函式
現在如果我們用引數呼叫 Dog's
建構函式怎麼辦?
Dog dog = new Dog("Rex");
你知道父類中非私有的成員是由子類繼承的,這意味著 Dog
也將具有 name
欄位。
在這種情況下,我們將引數傳遞給建構函式。它依次將引數傳遞給父類的建構函式,並使用引數初始化 name
欄位。
輸出將是
Animal's constructor with 1 parameter
Rex
Dog's constructor with 1 parameter
Rex
摘要:
每個物件建立都從基類開始。在繼承中,層次結構中的類是連結的。由於所有類都來自 Object
,因此在建立任何物件時要呼叫的第一個建構函式是 Object
類建構函式; 然後呼叫鏈中的下一個建構函式,並且只有在呼叫它們之後才建立物件
基本關鍵字
- base 關鍵字用於從派生類中訪問基類的成員:
- 在已被另一個方法重寫的基類上呼叫方法。指定在建立派生類的例項時應呼叫哪個基類建構函式。