简体   繁体   English

C#中的抽象类构造函数

[英]Abstract class constructor in C#

In c# we can't create an obeject of a abstact class or interface it means abstract class do not have any constructor, is it true ? 在c#中,我们无法创建一个抽象类或接口的对象,这意味着抽象类没有任何构造函数,是真的吗? or if it have then what is it's purpose there? 或者如果它有那么它的目的是什么?

As others have said, abstract classes usually have constructors (either explicitly or the default one created by the compiler) - and any derived class constructor will have to chain through the abstract class's constructor in the normal way. 正如其他人所说,抽象类通常具有构造函数(显式或默认的编译器) - 并且任何派生类构造函数都必须以正常方式链接抽象类的构造函数。 That's the important bit... suppose you have an abstract class which stores the name associated with an instance - because you always want a name, and you don't want to write the Name property in each concrete derived class. 这是重要的一点......假设您有一个抽象类,它存储与实例关联的名称 - 因为您总是需要一个名称,并且您不希望在每个具体的派生类中编写Name属性。 You might provide a constructor which takes that name and assigns it to a field... and then every subclass constructor would have to go through that constructor, so that you still knew you'd always have a name. 您可以提供一个构造函数,它接受该名称并将其分配给一个字段......然后每个子类构造函数都必须通过该构造函数,这样您仍然知道您总是有一个名称。 If you want to know more about constructor chaining, read my article on it . 如果您想了解有关构造函数链接的更多信息,请阅读我的文章

Here's an example of that: 这是一个例子:

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
}

To further answer your comment on BoltClock's answer, asbtract classes can't have private abstract methods, but they can have private constructors. 为了进一步回答你对BoltClock答案的评论,asbtract类不能有私有抽象方法,但它们可以有私有构造函数。 Indeed, it's sometimes useful to have only private constructors in an abstract class, because it means the class can only be derived from within the program text of the same class . 实际上,在抽象类中只有私有构造函数有时很有用,因为它意味着类只能从同一个类的程序文本中派生。 This allows you to create pseudo-enums: 这允许您创建伪枚举:

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;
        }
    }
}

In this respect, an abstract private method/property could make sense - it could be accessed by the base class but provided by the derived classes within the same class's program text. 在这方面,抽象的私有方法/属性可能有意义 - 它可以由基类访问,但由同一类的程序文本中的派生类提供。 However, it's prohibited by the specification. 但是,规范禁止它。 Usually, protected abstract members would solve the same problem - but not quite always. 通常, protected抽象成员会解决同样的问题 - 但并不总是如此。

Good question. 好问题。 Here's why Abstract classes need constructors even though they cannot be instantited. 这就是为什么抽象类需要构造函数,即使它们无法即时生成。

In any Object oriented language like C#, object construction is an hierarchical process. 在任何面向对象的语言(如C#)中,对象构造是一个分层过程。 Look at the code below. 看下面的代码。 When you instantiate any object of type DerivedClass, it must construct the base object first before creating the object of typeof DerivedClass. 当您实例化DerivedClass类型的任何对象时,它必须在创建typeof DerivedClass的对象之前首先构造基础对象。 Here the base class may or may not be an Abstract class. 这里的基类可能是也可能不是抽象类。 But even when you instantiate an object of a concrete type derived from an abstract class it will still need to call the constructor of the Base class before the object of DerivedClass type is created, hence you always need a constructor for Abstract class. 但即使你实例化一个从抽象类派生的具体类型的对象,它仍然需要在创建DerivedClass类型的对象之前调用Base类的构造函数,因此你总是需要一个Abstract类的构造函数。 If you have not added any constructor, C# compiler will automatically add a public parameterless constructor to the class in the generated MSIL. 如果您尚未添加任何构造函数,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 : Assuming, If Abstract base classes are not allowed to have constructors because they need not be instantiated, the whole fundamentals of the object oriented programming will go on toss. PS :假设,如果不允许抽象基类具有构造函数,因为它们不需要实例化,那么面向对象编程的整个基础将继续折腾。 The idea behind Abstract types are to represent objects that have some features and behaviours but not complete as whole to allow independant existence. 抽象类型背后的想法是表示具有某些特征和行为但不完整的对象以允许独立存在。

No. it means that operator new is not allowed to create object from this type of class. 不,这意味着不允许operator new从这种类创建对象。

The purpose might be that are allocated/initialized some properties of class. 目的可能是分配/初始化类的一些属性。

abstract usually leave some methods to implement. 摘要通常会留下一些方法来实现。

Regarding the interface, this structure holds only the signatures of method, delegates or events. 关于接口,此结构仅包含方法,委托或事件的签名。 That may be implemented in class that use interface. 这可以在使用接口的类中实现。 You cant create a object. 你不能创建一个对象。

Read about new 阅读新的

EDIT: 编辑:

What is the purpose of constructor in abstract class ? 抽象类中构造函数的用途是什么?

When one class inherit another class, the parent class of it had to be created first while object is crated. 当一个类继承另一个类时,必须首先创建它的父类,而对象是crated。 In class do not implement some special constructor always is used default one [className()]. 在类中没有实现一些特殊的构造函数总是使用默认的[className()]。 When you override some method then the implementation of functionality is taken form class which override the method. 当您重写某个方法时,功能的实​​现将从类覆盖该方法。 This is why method used in constructor should never be virtual. 这就是构造函数中使用的方法永远不应该是虚拟的原因。 Same logic for abstract class, such class can have a lot of functionality, and only one method that should be implemented by child class. 抽象类的逻辑相同,这样的类可以有很多功能,只有一个应该由子类实现的方法。

Abstract classes have constructors but you can't call them directly as you can't directly instantiate abstract classes. 抽象类具有构造函数,但您无法直接调用它们,因为您无法直接实例化抽象类。

To answer your comment, the concept of a private abstract method or property makes no sense, because private prevents anybody else from accessing it, and abstract prevents itself from accessing it. 要回答你的评论,私有抽象方法或属性的概念是没有意义的,因为private防止任何其他人访问它, abstract阻止自己访问它。 So there would essentially be no possible way to call it. 因此基本上没有可能的方法来调用它。

EDIT: see Jon Skeet's answer on private constructors. 编辑:参见Jon Skeet对私人建筑师的回答。 Private members of other kinds cannot exist in abstract classes, though. 但是,其他类型的私有成员不能存在于抽象类中。

Abstract classes do have constructors. 抽象类确实有构造函数。 When you create an instance of a derived class, its parent class' constructors are called. 创建派生类的实例时,将调用其父类的构造函数。 This applies to classes derived from abstract classes as well. 这也适用于从抽象类派生的类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM