为什么不能创建一个抽象类实例但可以调用它的构造函数?

时间:2014-09-29 07:39:50

标签: c# constructor abstract-class base

我知道我们无法创建一个抽象类实例,但我无法理解为什么可以使用base来调用抽象类的构造函数。

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

    public Fruit(string name)
    {
        Name = name;
    }
}

class Apple : Fruit
{
    public Apple(string name) : base(name) { }
}


Fruit f = new Fruit("Fruit");  // Coimple Error
Apple a = new Apple("Apple");  // Success
  • base关键字只调用构造函数,方法等?

  • 创建实例调用构造函数之间的区别是什么?

提前致谢。

4 个答案:

答案 0 :(得分:2)

只有派生类(例如Apple)可以使用特殊base字来调用其父(抽象类)的构造函数。无法直接调用(调用)构造函数。

答案 1 :(得分:1)

  

那个base关键字是否只调用构造函数,方法等?

不,任何时候想要显式调用父类'方法并避免在派生类中调用覆盖。虽然: base(...)语法对于构造函数是唯一的,但通常会调用base.method();

  

创建实例和调用构造函数之间有什么区别?

使用new运算符创建实例可以做很多事情:

  • 为对象分配内存
  • 初始化字段
  • 然后最后调用构造函数,如果指定的话,它将首先调用基础构造函数。

对此顺序的更深入解释是在这个答案中:https://stackoverflow.com/a/1882778/360211但这应该足以解释差异。

答案 2 :(得分:1)

我想补充一点,抽象类可能提供构造函数的事实并不意味着它还不是抽象的。

根据定义,抽象类是一个类,其中某些成员或者没有成员不提供默认实现,派生类必须为这些成员提供实现。另一方面,由于抽象类的一些成员只是签名 - 整个抽象成员 - ,代码必须无法实例化该类。

但是如果派生类(抽象或具体)无法调用基本抽象类构造函数,抽象类将缺少多态构造函数,并且可能无法初始化类属性或定义默认类初始化代码,即使该代码调用抽象方法或属性。

这是为什么派生类可以调用父类构造函数,即使该类是抽象的!

  

创建实例和调用a之间的区别是什么   构造

我们可能会试着通过对低级细节的深入解释来解决这个问题,但是 我觉得这更像是一个概念问题,而不是一个低级别的问题。

如果需要摘要,调用构造函数类实例化进程的一部分。这是一个在创建实例后调用的方法,并在任何其他代码可能使用该实例之前使用自定义代码初始化实例。

当你在构造函数中使用base关键字来调用父类的第一类时,你只是将构造函数调用从最派生类链接到基类。

答案 3 :(得分:0)

使用 new 关键字创建实例会创建一个新对象并返回对该对象的引用。使用base关键字调用构造函数不会创建对该对象的引用(它也不会创建它只是在构造函数中执行代码。

深入了解此答案以获取更多信息https://stackoverflow.com/a/14453366/3789232