【问题标题】:Add parameter when you inherit abstract class?继承抽象类时添加参数?
【发布时间】:2018-11-13 02:32:14
【问题描述】:

Book类继承抽象类Goods。 Book 方法与 Goods 方法具有相同的参数。而且还有numPages,这是为什么呢?

public Book(string title, string barCode, double price, int numPages)

如果我有一个类继承 Book 类,我是否必须将所有相同的参数都放入并创建一个新的?

public Author(string title, string barCode, double price, int numPages, string author)

我希望这有任何意义。

  abstract class Goods
    {
        public decimal weight; 
        string Title, BarCode;
        double Price;
        public Goods(string title, string barCode, double price)
        {
            Title = title;
            BarCode = barCode;
            Price = price;
        }
    }

    abstract class Book : Goods
    {
        protected int NumPages;
        public Book(string title, string barCode, double price, int numPages)
            : base(title, barCode, price)
        {
            NumPages = numPages;
            weight = 1;
        }

【问题讨论】:

  • Do you have to add a variable to a method that has :base? 否。您可以通过删除 NumPages 并验证它是否仍然有效来自行测试。
  • 具有:base"的"方法是一个构造函数。不,您没有必须向其中添加任何变量。但是我不清楚如果你想在子类的构造函数列表中添加一个变量,是否必须复制原始构造函数。 “向其中添加变量”是什么意思?换句话说,添加新属性(或在您的情况下为受保护的字段)而不在构造函数中为其添加初始化程序是非常好的。
  • 这个问题不太清楚。但是当涉及到抽象类时,如果你试图做一些你不能做的事情或不做你必须做的事情,编译器会给你一个错误。因此,如果问题是您必须做什么,这是一个简单的判断方法。或者你在问你应该怎么做?

标签: c# variables inheritance abstract base


【解决方案1】:

如果我有一个类继承 Book 类,我是否必须将所有相同的参数都放入并创建一个新的?

不,你不必,如果Book类可以在构造函数的开头为Goods类构造函数提供一些值。

public Book(string title, double price, int numPages)
    : base(title, price, 100) {

除非,只能在子类的构造函数中放入相同的参数。

因为

实例构造函数,您调用它来创建类的新实例。每个类都必须定义自己的构造函数。

Microsoft doc 中有解释,子类必须显式或隐式调用基类提供的构造函数之一。

: base(title, barCode, price) 在您的代码中是显式方式。即使Book类没有构造函数或者没有参数的构造函数,你也可以使用隐式方式,可以省略代码: base()

您可以考虑的另一件事是摆脱用于可选字段的构造函数参数。此类字段可以填充为属性。下面代码中的BarCode 就是示例。那么,子类就不需要有BarCode的代码了。

但是阅读this doc,请注意使用对象初始化器的初始化顺序。在某些情况下,它不能等价,尽管在提供的简单代码中并不重要。

abstract class Goods {
    public decimal weight;
    string Title, GoodsType;
    public string BarCode { get; set; }
    double Price;
    public Goods(string title, double price) {
        Title = title;
        GoodsType = goodsType;
        Price = price;
    }
}

class Book : Goods {
    protected int NumPages;
    public Book(string title, double price, int numPages)
        : base(title, price) {
        NumPages = numPages;
        weight = 1;
    }
}

【讨论】:

  • 问题中包含这样的短语,“...我是否也必须...制作一个新的”。答案是“不”。您可以添加带有新参数的构造函数来初始化属性/字段,但这不是必需的。在原始示例中,这是完全合法的语法:public Book() : base("", 0, "") { }。唯一的要求是如果显式定义了基类构造函数,则调用其中一个。
  • 从技术上讲,您根本没有定义一个(只要基类没有定义一个),因为 C# 将为您生成一个默认构造函数, 这会将所有字段初始化为其默认值 (link)
  • @RufusL 感谢您的指出。是的,这是正确的。我隐含地假设她在 Book 类中没有 Goods 构造函数的参数的默认值,因此我提到了 base(title, price, "book") 作为一个选项。但是,再次阅读我的答案,我认为你是对的。这样的假设会造成混乱。我会纠正它。我现在没有时间,所以我稍后会编辑我的答案。
  • @RufusL 就默认构造函数而言,我的意思是我的答案中的or implicitly 代表它。我将尝试更清楚地提及它。但我在想提供的具有带参数的构造函数的基本抽象类是这个问题的一部分。我想知道它是提供的代码的特定问题还是一般 c# 语法问题...
  • 我认为这是针对特定代码的,只是提供了一些额外的细节,因为黄色的第二个文本表示每个客户端必须定义自己的构造函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
相关资源
最近更新 更多