在c#中,我们无法创建抽象类或接口的对象,这意味着抽象类没有任何构造函数,是真的吗? 或者如果它有什么目的呢?
答案 0 :(得分:13)
正如其他人所说,抽象类通常具有构造函数(显式或默认的编译器) - 并且任何派生类构造函数都必须以正常方式链接抽象类的构造函数。这是重要的一点......假设你有一个抽象类来存储与实例关联的名称 - 因为你总是想要一个名字,而你不想写Name
每个具体派生类中的属性。你可以提供一个构造函数,它接受该名称并将其分配给一个字段......然后每个子类构造函数都必须通过该构造函数,这样你仍然知道你总是有一个名字。如果您想了解有关构造函数链接的更多信息,请阅读my article on it。
以下是一个例子:
public abstract class DemoBase
{
private readonly string name;
public string Name { get { return name; } }
protected DemoBase(string name)
{
this.name = name;
}
// Abstract members here, probably
}
public class FixedNameDemo : DemoBase
{
public FixedNameDemo()
: base ("Always the same name")
{
}
// Other stuff here
}
public class VariableNameDemo : DemoBase
{
public VariableNameDemo(string name)
: base(name)
{
}
// Other stuff here
}
要进一步回答您对BoltClock答案的评论,asbtract类不能拥有私有抽象方法,但可以拥有私有构造函数。实际上,在抽象类中只有只有私有构造函数是有用的,因为它意味着该类只能从同一类的程序文本中的派生。这允许您创建伪枚举:
public abstract class ArithmeticOperator
{
public static readonly ArithmeticOperator Plus = new PlusOperator();
public static readonly ArithmeticOperator Minus = new MinusOperator();
public abstract int Apply(int x, int y);
private ArithmeticOperator() {}
private class PlusOperator : ArithmeticOperator
{
public override int Apply(int x, int y)
{
return x + y;
}
}
private class MinusOperator : ArithmeticOperator
{
public override int Apply(int x, int y)
{
return x - y;
}
}
}
在这方面,抽象的私有方法/属性可以有意义 - 它可以由基类访问,但由同一类的程序文本中的派生类提供。但是,规范禁止它。通常,protected
抽象成员会解决同样的问题 - 但并不总是如此。
答案 1 :(得分:7)
好问题。这就是为什么抽象类需要构造函数,即使它们不能被瞬时化。
在任何面向对象的语言(如C#)中,对象构造是一个分层过程。看下面的代码。当您实例化DerivedClass类型的任何对象时,它必须在创建typeof DerivedClass的对象之前首先构造基础对象。这里的基类可能是也可能不是抽象类。但即使你实例化一个从抽象类派生的具体类型的对象,它仍然需要在创建DerivedClass类型的对象之前调用Base类的构造函数,因此你总是需要一个Abstract类的构造函数。如果您尚未添加任何构造函数,C#编译器将自动向生成的MSIL中的类添加公共无参数构造函数。
public class BaseClass
{
public BaseClass()
{
Console.WriteLine("BaseClass constructor called..");
}
}
public class DerivedClass : BaseClass
{
public DerivedClass()
{
Console.WriteLine("DerivedClass constructor called..");
}
}
DerivedClass obj = new DerivedClass();
//Output
//BaseClass constructor called..
//DerivedClass constructor called..
PS :假设,如果是抽象基类 不允许有构造函数 因为他们不需要实例化, 整个对象的基本面 面向编程将继续折腾。 抽象类型背后的想法是 代表有一些的对象 特征和行为但不是 完整整体允许独立 存在。
答案 2 :(得分:4)
没有。这意味着不允许operator new从这种类创建对象。
目的可能是分配/初始化类的一些属性。
摘要通常会留下一些方法来实现。
关于接口,此结构仅包含方法,委托或事件的签名。这可以在使用接口的类中实现。你不能创建一个对象。
了解new
编辑:
抽象类中构造函数的用途是什么?
当一个类继承另一个类时,必须首先创建它的父类,而对象是crated。在类中没有实现一些特殊的构造函数总是使用默认的[className()]。当您重写某个方法时,功能的实现将从类覆盖该方法。这就是构造函数中使用的方法永远不应该是虚拟的原因。抽象类的逻辑相同,这样的类可以有很多功能,只有一个应该由子类实现的方法。
答案 3 :(得分:2)
抽象类有构造函数,但是你不能直接调用它们,因为你不能直接实例化抽象类。
要回答您的评论,私有抽象方法或属性的概念毫无意义,因为private
会阻止任何其他人访问它,而abstract
会阻止本身访问它。因此基本上没有可能的方式来调用它。
编辑:请参阅Jon Skeet对私人建筑师的回答。但是,其他类型的私有成员不能存在于抽象类中。
答案 4 :(得分:1)
抽象类确实有构造函数。创建派生类的实例时,将调用其父类的构造函数。这也适用于从抽象类派生的类。