OOP继承和默认构造函数

时间:2015-04-30 05:41:31

标签: oop constructor

假设有一个基类A和一个来自B的类A。 然后,我们知道类A的构造函数永远不会被类B继承。但是,当创建B的新对象时,则会调用类A的默认构造函数,然后调用类B的默认/自定义构造函数。也许这样做的目的是需要将类A的字段初始化为默认值。

现在,假设类A已定义了自定义构造函数。这意味着编译器会以静默方式删除类A的默认构造函数。现在,在创建类B的新实例时,在调用类A的构造函数之前会自动调用类B的构造函数? (在这种情况下,如何初始化类A字段?)

4 个答案:

答案 0 :(得分:57)

  

现在,在创建类B的新实例时,在调用类A构造函数之前会自动调用哪个类B的构造函数?

代码基本上无法编译。每个构造函数都必须隐式或显式地链接到另一个构造函数。它链接到的构造函数可以在同一个类(带有this)或基类(带base)。

像这样的构造函数:

public B() {}

隐含地:

public B() : base() {}

...如果你根本没有指定构造函数,它将以相同的方式隐式添加 - 但它仍然需要调用。例如,您的方案:

public class A
{
    public A(int x) {}
}

public class B : A {}

导致编译器错误:

  

错误CS7036:没有给出与'x'所需的形式参数'A.A(int)'对应的参数

但是,您可以明确指定不同的构造函数调用,例如

public B() : base(10) {} // Chain to base class constructor

public B() : this(10) {} // Chain to same class constructor, assuming one exists

答案 1 :(得分:6)

class A提供自己的构造函数后,class B对象创建期间不会发生自动调用。

class B构造函数中的第一行应为super(paramsToClassAConstructor),或者可以使用class B调用this()中的其他构造函数。 class B中的第二个构造函数负责在这种情况下调用class A构造函数。

答案 2 :(得分:3)

当构造函数完成执行时 - 对象处于有效的初始状态。我们应该使用有效的对象。
    当我们为A类提供非默认构造函数时 - 我们实际上是在说 - 构造A类对象,即处于有效的初始状态 - 我们需要更多的信息 - 由参数提供。
    鉴于此,编译器通过而不是生成默认构造函数。客户端代码将无法编译(因为它应该 - 我们将如何使对象落在有效状态?) - 客户端程序员必须坐下来注意。
    当你提供一个显式的空构造函数 - 你实际上在告诉编译器 - 我知道我在做什么 - 默认构造函数很可能会将字段初始化为一些合理的默认值。
    或者为了促进重用 - 默认构造函数可以使用一些默认值来调用非默认值     子类知道它的超类 - 子类构造函数可以调用超类方法 - (子类中一些常用的重用方法)。鉴于上述情况 - 这要求超类部分应处于有效状态 - 即其构造函数在其任何方法调用之前执行。这需要在子类构造函数之前调用超级构造函数     鉴于此 - 您可以轻松地设计构造函数以强制执行正确的初始状态行为

答案 3 :(得分:0)

定义基类参数构造函数没有特殊的规则。规则与其他类构造函数相同。您可以定义构造函数的数量,如下所示:

class baseclass
    {
        public baseclass()
        {

        }
        public baseclass(string message)
        {

        }
    }

如果基类具有构造函数,则需要子类或派生类从其基类调用构造函数。

class childclass : baseclass
    {
        public childclass()
        {
        }
        public childclass(string message)
            : base(message)
        {            
        }
    }