C#中的抽象类构造函数

时间:2010-10-14 05:15:56

标签: c# abstract-class

在c#中,我们无法创建抽象类或接口的对象,这意味着抽象类没有任何构造函数,是真的吗? 或者如果它有什么目的呢?

5 个答案:

答案 0 :(得分:13)

正如其他人所说,抽象类通常具有构造函数(显式或默认的编译器) - 并且任何派生类构造函数都必须以正常方式链接抽象类的构造函数。这是重要的一点......假设你有一个抽象类来存储与实例关联的名称 - 因为你总是想要一个名字,而你不想写Name每个具体派生类中的属性。你可以提供一个构造函数,它接受该名称并将其分配给一个字段......然后每个子类构造函数都必须通过该构造函数,这样你仍然知道你总是有一个名字。如果您想了解有关构造函数链接的更多信息,请阅读my article on it

以下是一个例子:

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抽象成员会解决同样的问题 - 但并不总是如此。

答案 1 :(得分:7)

好问题。这就是为什么抽象类需要构造函数,即使它们不能被瞬时化。

在任何面向对象的语言(如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 :假设,如果是抽象基类   不允许有构造函数   因为他们不需要实例化,   整个对象的基本面   面向编程将继续折腾。   抽象类型背后的想法是   代表有一些的对象   特征和行为但不是   完整整体允许独立   存在。

答案 2 :(得分:4)

没有。这意味着不允许operator new从这种类创建对象。

目的可能是分配/初始化类的一些属性。

摘要通常会留下一些方法来实现。

关于接口,此结构仅包含方法,委托或事件的签名。这可以在使用接口的类中实现。你不能创建一个对象。

了解new

编辑:

抽象类中构造函数的用途是什么?

当一个类继承另一个类时,必须首先创建它的父类,而对象是crated。在类中没有实现一些特殊的构造函数总是使用默认的[className()]。当您重写某个方法时,功能的实​​现将从类覆盖该方法。这就是构造函数中使用的方法永远不应该是虚拟的原因。抽象类的逻辑相同,这样的类可以有很多功能,只有一个应该由子类实现的方法。

答案 3 :(得分:2)

抽象类有构造函数,但是你不能直接调用它们,因为你不能直接实例化抽象类。

要回答您的评论,私有抽象方法或属性的概念毫无意义,因为private会阻止任何其他人访问它,而abstract会阻止本身访问它。因此基本上没有可能的方式来调用它。

编辑:请参阅Jon Skeet对私人建筑师的回答。但是,其他类型的私有成员不能存在于抽象类中。

答案 4 :(得分:1)

抽象类确实有构造函数。创建派生类的实例时,将调用其父类的构造函数。这也适用于从抽象类派生的类。