可以从基类构造函数中调用派生类构造函数吗?

3
我有一个抽象基类,从它派生出两个类。抽象类有一个受保护的字段,由派生类中的构造函数进行初始化。每个派生类都有两个构造函数,第一个构造函数初始化字段,第二个构造函数通过调用第一个构造函数修改第一个构造函数的初始化。两个派生类的第二个构造函数完全相同,但是第一个构造函数在两个派生类之间是不同的。是否有一种方法将第二个构造函数放在基类中?
以下是一个例子来说明我的意思:
public abstract class A {
    protected int[] field1;

    public void someMethod() {
        //somethingsomething
    }
}

public class B : A {
    public B() {
        //body X
        //this initializes field1 in some way
    }

    public B(bool p) : this() {
        //body Y
        //this initializes field1 in some way + modification
    }
}

public class C : A {
    public C() {
        //body Z
        //this initializes field1 in another way
    }

    public C(bool p) : this() {
        //body Y
        //this initializes field1 in another way + modification
    }
}

我想做的是找到一种方法,不必重复两次“body Y”。我考虑将B(bool p)C(bool p)中的“body Y”放在class A的构造函数A(bool p)中,然后让B(bool p)C(bool p)调用基类构造函数: base(bool p),随后是一个空的body。但是我发现基类构造函数必须调用派生类构造函数。
对我来说,这听起来很愚蠢。虽然我不确定,但我有这样的感觉:从基类调用派生类的内容只能在运行时完成,无法在编译时检查。我只是试图找到一种遵循DRY原则的方法。
谢谢。

10
不,你不能调用一个子类构造函数,但你可以将Y作为A的一个方法,在两个构造函数中都进行调用。 - D Stanley
好的,明白了。谢谢@DStanley。 - skwear
2个回答

3

简短回答:不行。这会违反面向对象的范式,所以你也不应该想要这样做。可以这样理解:抽象基类可以被任意数量的类扩展,但如果它与其中一个子类紧密耦合,那么其他子类会受到什么影响呢?

public class BaseClass {
     // Call child class constructor
     public BaseClass() : A() { }
 }

 public class A : BaseClass {
      public A() { ... }
 }

 // How should BaseClass handle this? There is no constructor named "A."
 public class B : BaseClass {
        public B() { ... }
 }

如果你希望基类和派生类共享一些功能,应该将其作为基类中的受保护方法。这样,你可以从构造函数中调用该方法。

你还可以在基类上创建一个构造函数,提供共同的功能,并使用 : base(...) 在子类中调用它。


0

基类唯一能够触发派生行为的方式是通过多态性(在B中有一个虚方法,并覆盖它)。

但在您的情况下,可能还有其他更直观的方式。例如:

public class C : A {
    public C() {
        //body Z
        //this initializes field1 in another way
    }

    public C(bool p) : base(p) {
        //this initializes field1 in another way + modification
    }
}

请注意,在您的示例中,B的默认构造函数调用了A的默认构造函数,而C的默认构造函数也调用了B的默认构造函数。
最后,您还可以考虑在A中添加第二个构造函数,该构造函数接收field1的初始值作为参数,但这取决于您的指令是否具有顺序依赖性。
如果您明确说明您的构造函数的确切作用,我可能会对您有更具决定性的答案。
此致敬礼

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接