簡體   English   中英

C# 繼承和默認構造函數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM