C#中抽象类的构造函数

Mul*_*der 193 c# constructor abstract-class

为什么可以在C#中为抽象类编写构造函数?
据我所知,我们无法实例化一个抽象类..那么它的用途是什么?
你无法实例化这个类,对吧?

Eri*_*ert 258

据我所知,我们无法实例化一个抽象类

那里有你的错误.当然,您可以实例化一个抽象类.

abstract class Animal {}
class Giraffe : Animal {}
...
Animal animal = new Giraffe();
Run Code Online (Sandbox Code Playgroud)

那里有一个动物实例.您通过创建一个从它派生的具体类来实例化一个抽象类,并实例化它.请记住,派生混凝土类的实例是其抽象基类的一个实例. 即使动物是抽象的,长颈鹿的实例也是动物的实例.

鉴于您可以实例化一个抽象类,它需要像任何其他类一样具有构造函数,以确保满足其不变量.

现在,静态类是一个实际上无法实例化的类,您会注意到在静态类中创建实例构造函数是不合法的.

  • 使用该逻辑,您可以获得接口实例:-) (19认同)
  • @Eric http://msdn.microsoft.com/en-us/library/sf985hc5.aspx说抽象类无法实例化 (5认同)
  • @supercat 不幸的是,这是一种语义误解,导致误用了多态性。长颈鹿“是”动物。Giraffe 的实例也是 Animal 的实例,并且必须在需要 Animal 实例的每个地方都可用。埃里克在这里是完全正确的。坚持认为 Giraffe 的实例不完全是 Animal 的实例会导致危险的反模式,例如允许 Rectangle 成为 Square 的子类,即使它不保持相同的不变量并且不能严格替换。 (4认同)
  • 从术语的角度来看,如果`Foo`是一个可继承的具体类型,和`DerivedFoo:Foo`,你会用什么术语来描述一个堆对象实例,它会将其类型报告为`Foo`,与`DerivedFoo`不同?我自己的倾向是使用短语"T的一个实例"来指代其*精确*类型为T的东西.否则我倾向于说"T或某些衍生物","T的一些衍生物". ","T"的一些实现,或"满足T的东西"取决于T是具体类,抽象类,接口还是约束. (3认同)
  • @ M.Babcock:运行static*initializers*,但不创建该类型的*instance*. (3认同)
  • 不要在面试中说“当然你可以实例化一个抽象类”。 (2认同)

Cra*_*nec 245

因为可能有一种标准方法要在抽象类中实例化数据.这样,您可以从该类继承的类调用基础构造函数.

public abstract class A{

    private string data;

    protected A(string myString){
      data = myString;
    }

}

public class B : A {

     B(string myString) : base(myString){}

}
Run Code Online (Sandbox Code Playgroud)

  • 评论中的代码非常容易阅读.我喜欢这个. (4认同)
  • 是的,如果我理解正确的话.您无法实例化抽象类本身,但派生类仍然具有基类的所有部分.它不仅有效,它是你做这件事的主要原因之一. (3认同)
  • 但是抽象类被定义为一个我们无法实例化它的类..如果我用它来初始化基类的readonly变量,它是抽象的,它可以吗? (2认同)

Rod*_*man 23

这是一种强制抽象类的一组不变量的方法.也就是说,无论子类做什么,您都希望确保基类的某些内容始终正确...示例:

abstract class Foo
{
    public DateTime TimeCreated {get; private set;}

    protected Foo()
    {
         this.TimeCreated = DateTime.Now;
    }
}

abstract class Bar : Foo
{
    public Bar() : base() //Bar's constructor's must call Foo's parameterless constructor.
    { }
}
Run Code Online (Sandbox Code Playgroud)

不要将构造函数视为new运算符的对偶.构造函数的唯一目的是确保在开始使用之前对象处于有效状态.恰好是我们通常通过new运营商称呼它.

  • 你不需要在派生类的构造函数上调用`base()`.它会被自动调用,因为那是无参数构造函数.这意味着你的构造函数等同于`public Bar(){}`. (5认同)
  • 旁注/评论;我喜欢你使用这些词;奇数和偶数在同一个句子中。 (4认同)

akh*_*hil 7

添加以上答案和示例。

是的,抽象类可以有构造函数,即使抽象类无法实例化。将解释抽象类构造函数 C# 代码示例。但是,也可能会出现下一个问题,如果我们无法实例化(使用 new 构造对象)抽象类,那么构造函数在抽象类中是什么,或者我们为什么要在抽象类中使用构造函数?

请注意,当我们创建派生类的对象时,即使我们无法实例化抽象类,也会隐式调用抽象基类的构造函数。例如在程序中,如果我们创建派生类的对象,那么抽象基类的构造函数也会被调用。

这也是例子之一

例子

abstract class A
{
    protected A() {Console.WriteLine("Abstract class constructor"); }
}
//Derived class
class B : A
{
   public B() {Console.WriteLine("Derived class constructor"); }
}

class Program
{
    static void Main(string[] args)
    {
        B obj = new B();
    }
}
Run Code Online (Sandbox Code Playgroud)

输出将是

Abstract class constructor
Derived class constructor
Run Code Online (Sandbox Code Playgroud)


Sak*_*kib 6

抽象类的要点

  1. 抽象类不能被实例化。
  2. 抽象类可以有构造函数和析构函数。
  3. 抽象类不能是密封类,因为 seal 修饰符会阻止类被继承。
  4. 抽象类包含抽象成员和非抽象成员。
  5. 抽象类成员可以是私有的、受保护的和内部的。
  6. 抽象成员不能具有私有访问修饰符。
  7. 抽象成员是隐式虚拟的,必须由非抽象派生类实现。


小智 5

它可以强制执行抽象类的所有实现所需的一些初始化逻辑,或者您在抽象类上实现的任何方法(并非抽象类中的所有方法都必须是抽象的,有些可以实现).

从您的抽象基类继承的任何类都必须调用基础构造函数.