C#中抽象类的构造方法
为什么可以在C#中为抽象类编写构造函数?
据我所知,我们不能实例化一个抽象类。所以它是什么?
你不能实例化这个类,对吧?
因为可能有一个标准的方法来实例化抽象类中的数据。 这样你就可以让inheritance自这个类的类调用基类的构造函数。
public abstract class A{ private string data; protected A(string myString){ data = myString; } } public class B : A { B(string myString) : base(myString){} }
据我所知,我们不能实例化一个抽象类
那里有你的错误。 当然你可以实例化一个抽象类。
abstract class Animal {} class Giraffe : Animal {} ... Animal animal = new Giraffe();
那里有一个动物的例子。 你通过派生一个具体的类来实例化一个抽象类,并实例化它。 请记住,派生的具体类的一个实例也是其抽象基类的一个实例。 即使动物是抽象的,长颈鹿也是动物的一个实例。
鉴于你可以实例化一个抽象类,它需要像任何其他类一样的构造函数,以确保它的不变式被满足。
现在,一个静态类是一个你实际上不能实例化的类,你会注意到在一个静态类中创build一个实例构造函数是不合法的。
这是强制抽象类的一组不variables的一种方式。 也就是说,不pipe子类是什么,你都想要确保基类中的某些东西总是如此…例如:
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
操作员来调用它。
在那里执行抽象类的所有实现所需的一些初始化逻辑,或者在抽象类中实现的任何方法(并非抽象类中的所有方法都必须是抽象的,有些可以实现的)。
从你的抽象基类inheritance的任何类将被迫调用基础构造函数。
通常构造函数涉及初始化正在创build的对象的成员。 在inheritance的概念中,通常inheritance层次结构中的每个类构造函数都负责实例化自己的成员variables。 这是有道理的,因为实例化必须在variables被定义的地方完成。
由于抽象类不是完全抽象的(与接口不同),抽象类和具体成员都是混合的,而不是抽象的成员需要初始化,这是在抽象类的构造函数中完成的,必须有构造函数在抽象类中。 当然,抽象类的构造函数只能从派生类的构造函数中调用。
你可以在实现所有方法后实例化它。 然后构造函数将被调用。
我也想在抽象的表面上做一些闪光所有的答案已经涵盖了几乎所有的东西。 还有我的2美分
抽象类是正常的类,有一些例外
- 你的这个类的任何客户/消费者都不能创build这个类的对象,它永远不意味着它的构造函数将永远不会调用。 它的派生类可以select调用哪个构造函数(如某些答案所示)
- 它可能有抽象的function。
在可inheritance的具体类中定义具有公共或内部存储类的构造函数有效地定义了两种方法:
-
一个方法(我将调用
InitializeThing
)作用this
,没有返回值,只能从Thing
的CreateThing
和InitializeThing
方法和子类InitializeXXX
方法调用。 -
一个方法(我将调用
CreateThing
),它返回构造函数的指定types的对象,基本上行为如下:Thing CreateThing(int whatever) { Thing result = AllocateObject<Thing>(); Thing.initializeThing(whatever); }
抽象类有效地创build只有第一种forms的方法。 从概念上讲,上面描述的两个“方法”应该需要具有相同的访问说明符是没有道理的。 然而,在实践中,没有办法以不同的方式指定其可访问性。 请注意,就实际实现而言,至less在.NET中, CreateThing
并不是真正实现为可调用方法,而是代表在newThing = new Thing(23);
处插入的代码序列newThing = new Thing(23);
声明。
一个抽象类可以具有需要初始化的成员variables,所以它们可以在抽象类构造函数中初始化,并且在派生类对象被初始化时调用该构造函数。
有以下两个重要特性阻止inheritanceAbstract类
-
抽象类必须具有抽象方法,否则它不是抽象类
-
抽象类必须由派生类inheritance,所以如果一个类被其他类inheritance,而不是被用来创build那个类的对象
从https://msdn.microsoft.com/en-us/library/ms182126.aspx
抽象types的构造函数只能由派生types调用。 因为公共构造函数创build一个types的实例,并且不能创build抽象types的实例,所以具有公共构造函数的抽象types被错误地devise。
因为只有派生类可以使用抽象类构造函数,所以如果需要,抽象类构造函数必须声明为protected
。
然而,这说VS编译器不会抱怨(与默认规则)时,在抽象类中声明公共构造函数,但它不会允许创build一个新的实例。