繁体   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