C# 中的抽象类构造函数

发布于 2024-09-28 02:14:26 字数 67 浏览 4 评论 0原文

在 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 ?
or if it have then what is it's purpose there?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

温暖的光 2024-10-05 02:14:26

正如其他人所说,抽象类通常具有构造函数(无论是显式的还是编译器创建的默认构造函数),并且任何派生类构造函数都必须以正常方式链接抽象类的构造函数。这是重要的一点......假设您有一个抽象类,它存储与实例关联的名称 - 因为您总是想要一个名称,并且您不想编写Name< /code> 每个具体派生类中的属性。您可以提供一个构造函数,该构造函数采用该名称并将其分配给一个字段...然后每个子类构造函数都必须经过该构造函数,以便您仍然知道您始终有一个名称。如果您想了解有关构造函数链的更多信息,请阅读我的文章

下面是一个例子:

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

在这方面,抽象私有方法/属性可能有意义 - 它可以由基类访问,但由同一类的程序文本中的派生类提供。然而,这是规范所禁止的。通常,受保护的抽象成员可以解决相同的问题 - 但并非总是如此。

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. 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. 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.

没有你我更好 2024-10-05 02:14:26

好问题。这就是为什么抽象类需要构造函数,尽管它们不能被实例化。

在任何面向对象的语言(如 C#)中,对象构造都是一个分层过程。看下面的代码。当实例化任何 DerivedClass 类型的对象时,必须先构造基对象,然后再创建 DerivedClass 类型的对象。这里的基类可能是也可能不是抽象类。但是,即使您实例化从抽象类派生的具体类型的对象,它仍然需要在创建 DerivedClass 类型的对象之前调用基类的构造函数,因此您始终需要抽象类的构造函数。如果没有添加任何构造函数,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:假设,如果抽象基类
不允许有构造函数
因为它们不需要被实例化,
对象的全部基础
面向编程就要折腾下去。
抽象类型背后的想法是
代表具有某些属性的对象
特征和行为,但不是
整体完整以允许独立
存在。

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. 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. 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. If you have not added any constructor, C# compiler will automatically add a public parameterless constructor to the class in the generated 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.
The idea behind Abstract types are to
represent objects that have some
features and behaviours but not
complete as whole to allow independant
existence.

囍孤女 2024-10-05 02:14:26

不,这意味着不允许 new 运算符从此类类型创建对象。

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

抽象通常留下一些方法来实现。

对于接口,该结构仅保存方法、委托或事件的签名。这可以在使用接口的类中实现。你无法创建一个对象。

阅读

编辑:

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

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

No. it means that operator new is not allowed to create object from this type of class.

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. In class do not implement some special constructor always is used default one [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.

吾家有女初长成 2024-10-05 02:14:26

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

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

编辑:请参阅 Jon Skeet 关于私有构造函数的答案。但是,其他类型的私有成员不能存在于抽象类中。

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. So there would essentially be no possible way to call it.

EDIT: see Jon Skeet's answer on private constructors. Private members of other kinds cannot exist in abstract classes, though.

忆梦 2024-10-05 02:14:26

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文