簡體   English   中英

C#中的抽象類構造函數

[英]Abstract class constructor in C#

在c#中,我們無法創建一個抽象類或接口的對象,這意味着抽象類沒有任何構造函數,是真的嗎? 或者如果它有那么它的目的是什么?

正如其他人所說,抽象類通常具有構造函數(顯式或默認的編譯器) - 並且任何派生類構造函數都必須以正常方式鏈接抽象類的構造函數。 這是重要的一點......假設您有一個抽象類,它存儲與實例關聯的名稱 - 因為您總是需要一個名稱,並且您不希望在每個具體的派生類中編寫Name屬性。 您可以提供一個構造函數,它接受該名稱並將其分配給一個字段......然后每個子類構造函數都必須通過該構造函數,這樣您仍然知道您總是有一個名稱。 如果您想了解有關構造函數鏈接的更多信息,請閱讀我的文章

這是一個例子:

public abstract class DemoBase
{
    private readonly string name;    
    public string Name { get { return name; } }

    protected DemoBase(string name)
    {
        this.name = name;
    }

    // Abstract members here, probably
}

public class FixedNameDemo : DemoBase
{
    public FixedNameDemo()
        : base ("Always the same name")
    {
    }

    // Other stuff here
}

public class VariableNameDemo : DemoBase
{
    public VariableNameDemo(string name)
        : base(name)
    {
    }

    // Other stuff here
}

為了進一步回答你對BoltClock答案的評論,asbtract類不能有私有抽象方法,但它們可以有私有構造函數。 實際上,在抽象類中只有私有構造函數有時很有用,因為它意味着類只能從同一個類的程序文本中派生。 這允許您創建偽枚舉:

public abstract class ArithmeticOperator
{
    public static readonly ArithmeticOperator Plus = new PlusOperator();
    public static readonly ArithmeticOperator Minus = new MinusOperator();

    public abstract int Apply(int x, int y);

    private ArithmeticOperator() {}

    private class PlusOperator : ArithmeticOperator
    {
        public override int Apply(int x, int y)
        {
            return x + y;
        }
    }

    private class MinusOperator : ArithmeticOperator
    {
        public override int Apply(int x, int y)
        {
            return x - y;
        }
    }
}

在這方面,抽象的私有方法/屬性可能有意義 - 它可以由基類訪問,但由同一類的程序文本中的派生類提供。 但是,規范禁止它。 通常, protected抽象成員會解決同樣的問題 - 但並不總是如此。

好問題。 這就是為什么抽象類需要構造函數,即使它們無法即時生成。

在任何面向對象的語言(如C#)中,對象構造是一個分層過程。 看下面的代碼。 當您實例化DerivedClass類型的任何對象時,它必須在創建typeof DerivedClass的對象之前首先構造基礎對象。 這里的基類可能是也可能不是抽象類。 但即使你實例化一個從抽象類派生的具體類型的對象,它仍然需要在創建DerivedClass類型的對象之前調用Base類的構造函數,因此你總是需要一個Abstract類的構造函數。 如果您尚未添加任何構造函數,C#編譯器將自動向生成的MSIL中的類添加公共無參數構造函數。

public class BaseClass
{
    public BaseClass() 
    {
        Console.WriteLine("BaseClass constructor called..");
    }
}

public class DerivedClass : BaseClass
{
    public DerivedClass()
    {
        Console.WriteLine("DerivedClass constructor called..");
    }
}

DerivedClass obj = new DerivedClass();

//Output
//BaseClass constructor called..
//DerivedClass constructor called..

PS :假設,如果不允許抽象基類具有構造函數,因為它們不需要實例化,那么面向對象編程的整個基礎將繼續折騰。 抽象類型背后的想法是表示具有某些特征和行為但不完整的對象以允許獨立存在。

不,這意味着不允許operator new從這種類創建對象。

目的可能是分配/初始化類的一些屬性。

摘要通常會留下一些方法來實現。

關於接口,此結構僅包含方法,委托或事件的簽名。 這可以在使用接口的類中實現。 你不能創建一個對象。

閱讀新的

編輯:

抽象類中構造函數的用途是什么?

當一個類繼承另一個類時,必須首先創建它的父類,而對象是crated。 在類中沒有實現一些特殊的構造函數總是使用默認的[className()]。 當您重寫某個方法時,功能的實​​現將從類覆蓋該方法。 這就是構造函數中使用的方法永遠不應該是虛擬的原因。 抽象類的邏輯相同,這樣的類可以有很多功能,只有一個應該由子類實現的方法。

抽象類具有構造函數,但您無法直接調用它們,因為您無法直接實例化抽象類。

要回答你的評論,私有抽象方法或屬性的概念是沒有意義的,因為private防止任何其他人訪問它, abstract阻止自己訪問它。 因此基本上沒有可能的方法來調用它。

編輯:參見Jon Skeet對私人建築師的回答。 但是,其他類型的私有成員不能存在於抽象類中。

抽象類確實有構造函數。 創建派生類的實例時,將調用其父類的構造函數。 這也適用於從抽象類派生的類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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