[英]C# inheritance and default constructors
假设有一个基类A
和一个从A
派生的类B
然后,我们知道类A
的构造函数永远不会被类B
继承。 但是,当创建B
的新对象时, - 在调用类B
的默认/自定义构造函数之前调用类A
的默认构造函数。 也许这样做的目的是需要将A
类的字段初始化为默认值。
现在,假设类A
定义了一个自定义构造函数。 这意味着类A
的默认构造函数会被编译器悄悄删除。 现在,在创建类B
的新实例时,在调用类B
的构造函数之前会自动调用类A
哪个构造函数? (在这种情况下如何初始化A
类字段?)
现在,在创建类
B
的新实例时,在调用类B
构造函数之前会自动调用类A
哪个构造函数?
基本上,代码将无法编译。 每个构造函数都必须隐式或显式地链接到另一个构造函数。 它链接到的构造函数可以在同一个类(与this
)或基类(与base
)。
像这样的构造函数:
public B() {}
是隐含的:
public B() : base() {}
...如果你根本不指定构造函数,它将以相同的方式隐式添加 - 但它仍然必须有一些东西可以调用。 例如,您的场景:
public class A
{
public A(int x) {}
}
public class B : A {}
导致编译器错误:
错误 CS7036:没有给出对应于
'AA(int)'
的所需形式参数'x'
的参数
但是,您可以显式指定不同的构造函数调用,例如
public B() : base(10) {} // Chain to base class constructor
或者
public B() : this(10) {} // Chain to same class constructor, assuming one exists
一旦您为class A
提供了自己的构造函数,在class B
对象创建期间就不会发生自动调用。
class B
构造函数中的第一行应该是super(paramsToClassAConstructor)
或者它可以使用this()
调用class B
中的另一个构造函数。 在这种情况下, class B
中的第二个构造函数负责调用class A
构造函数。
当构造函数完成执行时 - 对象处于有效的初始状态。 我们应该使用有效的对象。
当我们为 A 类提供非默认构造函数时——我们实际上是在说——构造 A 类对象,即处于有效的初始状态——我们需要更多信息——这是由参数提供的。
鉴于此,编译器通过不生成默认构造函数来提供帮助。 客户端代码将无法编译(因为它应该编译 - 我们还能如何使对象处于有效状态?) - 客户端程序员将不得不坐下来注意。
当你提供一个显式的空构造函数时——你实际上是在告诉编译器——我知道我在做什么——默认构造函数很可能会将字段初始化为一些合理的默认值。
或者为了促进重用 - 默认构造函数可以使用一些默认值调用非默认构造函数。
子类知道它的超类——子类构造函数可以调用超类方法——(子类中一些常用的重用方法)。 鉴于上述 - 这要求超类部分应该处于有效状态 - 即它的构造函数在其任何方法调用之前执行。 这需要在子类构造函数之前调用超级构造函数。
鉴于此 - 您将能够轻松地设计构造函数以强制执行正确的初始状态行为。
定义基类参数构造函数没有特殊规则。 规则与其他类构造函数相同。 您可以定义构造函数的数量如下:
class baseclass
{
public baseclass()
{
}
public baseclass(string message)
{
}
}
如果基类有构造函数,那么子类或派生类需要从其基类调用构造函数。
class childclass : baseclass
{
public childclass()
{
}
public childclass(string message)
: base(message)
{
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.