可能重复:
Why can’t I create an abstract constructor on an abstract C# class?
为什么我不能像这样声明抽象类我的类的构造函数:
public abstract class MyClass {
public abstract MyClass(int param);
}
答案 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)
根据定义,该类无法直接实例化,因此从某种意义上说,它已经是抽象的。