[英]C# inheritance and default constructors
假設有一個基類A
和一個從A
派生的類B
然后,我們知道類A
的構造函數永遠不會被類B
繼承。 但是,當創建B
的新對象時, - 在調用類B
的默認/自定義構造函數之前調用類A
的默認構造函數。 也許這樣做的目的是需要將A
類的字段初始化為默認值。
現在,假設類A
定義了一個自定義構造函數。 這意味着類A
的默認構造函數會被編譯器悄悄刪除。 現在,在創建類B
的新實例時,在調用類B
的構造函數之前會自動調用類A
哪個構造函數? (在這種情況下如何初始化A
類字段?)
現在,在創建類
B
的新實例時,在調用類B
構造函數之前會自動調用類A
哪個構造函數?
基本上,代碼將無法編譯。 每個構造函數都必須隱式或顯式地鏈接到另一個構造函數。 它鏈接到的構造函數可以在同一個類(與this
)或基類(與base
)。
像這樣的構造函數:
public B() {}
是隱含的:
public B() : base() {}
...如果你根本不指定構造函數,它將以相同的方式隱式添加 - 但它仍然必須有一些東西可以調用。 例如,您的場景:
public class A
{
public A(int x) {}
}
public class B : A {}
導致編譯器錯誤:
錯誤 CS7036:沒有給出對應於
'AA(int)'
的所需形式參數'x'
的參數
但是,您可以顯式指定不同的構造函數調用,例如
public B() : base(10) {} // Chain to base class constructor
或者
public B() : this(10) {} // Chain to same class constructor, assuming one exists
一旦您為class A
提供了自己的構造函數,在class B
對象創建期間就不會發生自動調用。
class B
構造函數中的第一行應該是super(paramsToClassAConstructor)
或者它可以使用this()
調用class B
中的另一個構造函數。 在這種情況下, class B
中的第二個構造函數負責調用class A
構造函數。
當構造函數完成執行時 - 對象處於有效的初始狀態。 我們應該使用有效的對象。
當我們為 A 類提供非默認構造函數時——我們實際上是在說——構造 A 類對象,即處於有效的初始狀態——我們需要更多信息——這是由參數提供的。
鑒於此,編譯器通過不生成默認構造函數來提供幫助。 客戶端代碼將無法編譯(因為它應該編譯 - 我們還能如何使對象處於有效狀態?) - 客戶端程序員將不得不坐下來注意。
當你提供一個顯式的空構造函數時——你實際上是在告訴編譯器——我知道我在做什么——默認構造函數很可能會將字段初始化為一些合理的默認值。
或者為了促進重用 - 默認構造函數可以使用一些默認值調用非默認構造函數。
子類知道它的超類——子類構造函數可以調用超類方法——(子類中一些常用的重用方法)。 鑒於上述 - 這要求超類部分應該處於有效狀態 - 即它的構造函數在其任何方法調用之前執行。 這需要在子類構造函數之前調用超級構造函數。
鑒於此 - 您將能夠輕松地設計構造函數以強制執行正確的初始狀態行為。
定義基類參數構造函數沒有特殊規則。 規則與其他類構造函數相同。 您可以定義構造函數的數量如下:
class baseclass
{
public baseclass()
{
}
public baseclass(string message)
{
}
}
如果基類有構造函數,那么子類或派生類需要從其基類調用構造函數。
class childclass : baseclass
{
public childclass()
{
}
public childclass(string message)
: base(message)
{
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.