C#中的抽象构造函数

时间:2010-02-19 19:33:26

标签: c# .net constructor abstract-class

  

可能重复:
  Why can’t I create an abstract constructor on an abstract C# class?

为什么我不能像这样声明抽象类我的类的构造函数:

public abstract class MyClass {
    public abstract MyClass(int param);
}

8 个答案:

答案 0 :(得分:70)

构造函数仅适用于定义它们的类,即它们不是继承的。使用基类构造函数(您必须调用其中一个,即使只是自动调用默认值),但不会通过派生类重写。您可以在抽象基类上定义构造函数 - 它不能直接使用,但可以通过派生类来调用。你不能做的是强制派生类来实现特定的构造函数签名。

定义一个构造函数(通常是受保护的)是非常合理的,以便为所有派生类定义一些通用的设置代码。或许,当抽象类提供依赖于此设置的其他默认行为时,尤其如此。例如:

public abstract class Foo
{
     public string Name { get; private set; }

     protected Foo( string name )
     {
         this.Name = name;
     }
}

public class Bar : Foo
{
     public Bar() : base("bar")
     {
        ...
     }
}

答案 1 :(得分:12)

你不能声明它abstract,但你可以在抽象类上有一个构造函数;只需删除单词abstract并为其提供正文。

答案 2 :(得分:6)

摘要意味着虚拟。永远不能以多态方式调用非默认构造函数,因此构造函数不允许使用virtual和abstract。

如果在未来的C#版本中,泛型被增强以允许通过泛型类型参数调用非默认构造函数,则可以对构造函数进行多态调用,并且也可以添加虚拟和抽象构造函数。

答案 3 :(得分:6)

构造函数更接近静态方法而不是“常规”方法。与静态方法一样,它们可以重载,但不能覆盖。也就是说,它们不是继承的,但可以重新定义。

public BaseClass
{
   public BaseClass( String s ) { ... }
   public static void doIt ( String s ) { ... }
}

public SubClass extends BaseClass
{
   public SubClass( String s )  { ... }
   public static void doIt ( String s ) { ... }
}

public SubClass2 extends BaseClass
{
}

new SubClass( "hello" );
SubClass.doIt( "hello" ); 

new SubClass2( "hello" ); // NOK
SubClass2.doIt( "hello" ); // NOK

构造函数和静态方法永远不会动态调度(虚拟) - 您总是知道实例化的具体类型或静态方法的具体类。这就是为什么抽象构造函数抽象静态方法没有意义。这就是为什么你也不能在接口中指定构造函数和静态方法。

您甚至可以将构造函数视为静态工厂方法(并参阅corresponding pattern):

  MyClass obj = new MyClass(); // the way it is
  MyClass obj = MyClass.new(); // think of it like this

我唯一能看出定义抽象构造函数或抽象静态方法的情况是使用 reflection 。在这种情况下,您可以确保所有子类都重新定义相应的静态方法或构造函数。但反思是另一个话题......

注意:在Smalltalk等语言中,类是常规对象,您可以覆盖静态方法并使用抽象构造函数。但它不适用于Java,因为类不是“常规”对象,即使你可以用反射来获取它们。

答案 4 :(得分:4)

这有什么不妥:

public abstract class MyClass {
    protected MyClass(int param)
    {
    }
}

在这种情况下,您需要所有派生类调用基类构造函数。

答案 5 :(得分:3)

因为不支持抽象构造函数。

但是抽象类可以有一个构造函数。

答案 6 :(得分:1)

构造函数不是普通方法。它有一个特殊的用途,因此仅限于为此目的而有意义的语言功能。另见:Why do constructors not return values?

答案 7 :(得分:0)

根据定义,该类无法直接实例化,因此从某种意义上说,它已经是抽象的。