带构造函数的抽象类,强制继承类来调用它

时间:2015-02-17 18:21:28

标签: c#

可能重复, 我有构造函数XYZ(字符串名称)的抽象类。 我也有从该抽象类继承的类。如何强制继承类调用base(字符串名称)?现在我可以使用new Inherited(),它不会调用base construcotr。我想强制用户在继承的类中实现默认构造函数。

4 个答案:

答案 0 :(得分:11)

没有显式构造函数的类具有无参数构造函数。另一方面,如果使用参数并且没有无参数构造函数实现构造函数,则在没有参数的情况下,您的类将无法实例化。

换句话说:

public abstract class A 
{
    public A(string x) 
    {
    }
}

public class B : A 
{
    // If you don't add ": base(x)" 
    // your code won't compile, because A has a 
    // constructor with parameters!
    public B(string x) : base(x)
    {
    }
}

也就是说,如果A具有无参数构造函数(或没有显式构造函数),B将自动调用基础构造函数。您无需在此处编写任何其他内容。

否则,如果你的基类有一个无参数构造函数和一个带参数的构造函数,你不能强制派生类自动调用构造函数,除了默认的(即所谓的无参数构造函数)

解决方法

嗯,这里没有特殊的解决方法,但请注意C#支持构造函数和方法中的可选参数。

如果你想100%确定派生类将调用一个具体的基础构造函数,你可以使用带有可选参数的单个无参数构造函数来实现你的基类,并使用它来代替构造函数重载:

public class A
{
    public A(string x = "hello world") // or just string x = null
    {

    }
}

现在,如果B类派生AB将始终调用A的基本构造函数,因为x是可选的,并且它具有默认值值。

答案 1 :(得分:3)

  

如何强制继承的类调用base(string name)

将抽象类中的无参数构造函数设为私有,或者根本不添加它。这将强制所有派生类调用您指定的构造函数,否则将出现编译错误。

public abstract class BaseClass
{
    protected BaseClass(string parameter)
    {
    }
}

public class DerivedClass : BaseClass
{
    public DerivedClass()
    {
    }
}

最终会以

结束
'`Project.BaseClass`' does not contain a constructor that takes 0 arguments

答案 2 :(得分:1)

你不需要做任何事情。所有派生类构造函数必须调用基类构造函数(某些particularly evil hacks除外,您可能不需要担心)。如果在代码中没有显式指定,则暗示对基类的无参数构造函数的隐式调用。如果基类没有无参数构造函数(如果添加构造函数接受字符串并且不显式添加无参数构造函数),则该类将无法编译。

答案 3 :(得分:0)

我花了近半个小时的时间再次尝试一个抽象基类的排列,该抽象基类的默认构造函数标记为private,并带有4个参数的重载,而派生类仅具有4参数重载。使用最新的C#编译器(7.3),很明显在这种情况下:

  1. 派生类必须显式定义4参数重载。
  2. 派生类中对4参数重载的重载必须是明确的。

基类构造函数签名

public OperatingParameterBase (
    string pstrInternalName ,
    string pstrDisplayName ,
    T penmParameterType ,
    U penmDefaultParameterSource )

派生类构造器

internal OperatingParameter (
    string pstrInternalName ,
    string pstrDisplayName ,
    T penmParameterType ,
    U penmDefaultParameterSource )
    : base (
          pstrInternalName ,
          pstrDisplayName ,
          penmParameterType ,
          penmDefaultParameterSource )
{
}   // internal OperatingParameterExample constructor

我在派生类中展示了整个构造函数,以证明调用基类构造函数是其唯一的绝对要求。由于基本构造函数的工作与该讨论无关,因此我将其省略。