c#中抽象类的构造函数

为什么可以在c#中为抽象类编写构造函数?< br > 据我所知,我们不能实例化一个抽象类..那它是干什么用的呢?< br > 你不能实例化类,对吧?< / p >

235452 次浏览

因为在抽象类中可能有一种标准的方法来实例化数据。这样,就可以让继承自该类的类调用基构造函数。

public abstract class A{


private string data;


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


}


public class B : A {


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


}

您可以在实现所有方法之后实例化它。然后将调用构造函数。

这是一种强制抽象类的一组不变量的方法。也就是说,无论子类做什么,你都想确保基类的某些事情总是正确的……例子:

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

不要认为构造函数是new操作符的对偶。构造函数的唯一目的是在开始使用对象之前确保对象处于有效状态。它恰好是我们通常通过new操作符调用它。

它的存在是为了执行抽象类的所有实现所需要的一些初始化逻辑,或者在抽象类上实现的任何方法(并不是抽象类上的所有方法都必须是抽象的,有些方法可以实现)。

任何继承自抽象基类的类都必须调用基构造函数。

据我所知,我们不能实例化一个抽象类

这是你的误差。当然,您可以实例化一个抽象类。

abstract class Animal {}
class Giraffe : Animal {}
...
Animal animal = new Giraffe();

这里有一个动物的例子。通过创建从抽象类派生的具体类来实例化抽象类,然后实例化抽象类。记住,派生的具体类的实例是,它是其抽象基类的实例。长颈鹿的实例也是动物的实例,即使动物是抽象的。

假设您可以实例化一个抽象类,它需要像任何其他类一样有一个构造函数,以确保它的不变量得到满足。

现在,静态类是一个实际上不能实例化的类,而且你会注意到在静态类中创建实例构造函数是不合法的。

我也想在抽象的表面上发光 所有的答案几乎涵盖了所有的事情。还是我的2美分

抽象类是有一些例外的普通类

  1. 该类的任何客户端/消费者都不能创建该类的对象 类,这并不意味着它的构造函数永远不会调用。它的派生类可以选择调用哪个构造函数。(如某些回答所描述)
  2. 它可能具有抽象的功能。

在可继承的具体类Thing中定义具有公共或内部存储类的构造函数有效地定义了两个方法:

  • 一个作用于this的方法(我将称之为InitializeThing),没有返回值,只能从ThingCreateThingInitializeThing方法,以及子类的InitializeXXX方法调用。

  • 一个方法(我将称之为CreateThing),它返回构造函数指定类型的对象,本质上表现为:

    Thing CreateThing(int whatever)
    {
    Thing result = AllocateObject<Thing>();
    Thing.initializeThing(whatever);
    }
    

Abstract classes effectively create methods of only the first form. Conceptually, there's no reason why the two "methods" described above should need to have the same access specifiers; in practice, however, there's no way to specify their accessibility differently. Note that in terms of actual implementation, at least in .NET, CreateThing isn't really implemented as a callable method, but instead represents a code sequence which gets inserted at a newThing = new Thing(23); statement.

通常构造函数涉及初始化正在创建的对象的成员。在继承的概念中,通常继承层次结构中的每个类构造函数都负责实例化自己的成员变量。这是有意义的,因为实例化必须在定义变量的地方进行。

由于抽象类不是完全抽象的(不像接口),它是抽象成员和具体成员的混合,非抽象成员需要初始化,这是在抽象类的构造函数中完成的,因此在抽象类中有必要有构造函数。当然,抽象类的构造函数只能从派生类的构造函数调用。

抽象类可以有需要初始化的成员变量,因此可以在抽象类构造函数中初始化它们,并且在派生类对象初始化时调用该构造函数。

下面有两个重要的特性可以防止继承Abstract类

  1. 抽象类必须有抽象方法,否则就不是抽象类

  2. 抽象类必须被派生类继承,因此,如果一个类被其他类继承,那么用什么来创建该类的对象

https://msdn.microsoft.com/en-us/library/ms182126.aspx

抽象类型上的构造函数只能由派生类型调用。由于公共构造函数创建类型的实例,而不能创建抽象类型的实例,因此具有公共构造函数的抽象类型是不正确设计的。

由于只有派生类才能使用抽象类构造函数,因此抽象类构造函数(如果需要)必须声明为protected

然而,当在抽象类中声明公共构造函数时,VS编译器不会报错(默认规则),但是它不允许创建一个新实例。

你完全正确。我们不能实例化一个抽象类,因为抽象方法没有任何主体,即抽象方法不可能实现。但在某些情况下,你可能需要初始化基类的一些变量。 你可以使用@Rodrick建议的基地关键字来做到这一点。在这种情况下,我们需要在抽象类中使用构造函数

关于抽象类的要点

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

加上上面的答案和例子。

是的,抽象类可以有构造函数,即使抽象类不能被实例化。将解释一个抽象类构造函数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();
}
}

输出将是

Abstract class constructor
Derived class constructor