繁体   English   中英

C# 继承和默认构造函数

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM