C# 构造函数参数和继承

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13536993/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 08:56:37  来源:igfitidea点击:

Constructor Parameters and Inheritance

c#inheritanceconstructor

提问by Frank

New to OOP and I'm confused by how derived-class constructors work when inheriting from a base class in C#.

OOP 新手,我对从 C# 中的基类继承时派生类构造函数的工作方式感到困惑。

First the base class:

首先是基类:

class BaseClass
{
    private string BaseOutput = null;

    public BaseClass(string BaseString)
    {
        BaseOutput = BaseString;
    }

    public virtual void PrintLine()
    {
        Console.WriteLine(BaseOutput);
    }
}

Here is the derived class:

这是派生类:

class SubClass : BaseClass
{
    private string SubOutput = null;

    public SubClass(string BaseString, string SubString) : base(BaseString)
    {
        SubOutput = SubString;
    }

    public override void PrintLine()
    {
        Console.WriteLine(SubOutput);
    }
}

Finally, the main part of the program:

最后,程序的主要部分:

class Program
{
    static void Main(string[] args)
    {
        BaseClass theBase = new BaseClass("Text for BaseClass");
        SubClass theSub = new SubClass("2nd param", "Text for SubClass");

        theBase.PrintLine();
        theSub.PrintLine();

        Console.ReadKey();
    }
}

What I don't get is why, when calling the constructor for the derived class, I have to also pass the parameter that the base class needs. Shouldn't the BaseOutput field in the derived class just stay set to null if no value is assigned to it? Why can't something like this work:

我不明白的是为什么在调用派生类的构造函数时,我还必须传递基类需要的参数。如果没有分配值,派生类中的 BaseOutput 字段不应该保持设置为 null 吗?为什么不能像这样的工作:

public SubClass(string SubString) : base(BaseString)

Furthermore, when calling the constructor in this derived class, the first parameter has to be named the same as the one in the base class or else it throws an error. If I were to define a new string variable called AnotherString in the derived class, why wouldn't this work:

此外,在派生类中调用构造函数时,第一个参数必须与基类中的参数命名相同,否则会引发错误。如果我要在派生类中定义一个名为 AnotherString 的新字符串变量,为什么这不起作用:

public SubClass(string AnotherString, string SubString) : base(BaseString)

Lastly, when you do this the right way and type out this...

最后,当您以正确的方式执行此操作并输入此内容时...

public SubClass(string BaseString, string SubString) : base(BaseString)

...what is the first parameter in the SubClass constructor used for? It's not being assigned or used in any methods for my derived class. Why do I have to even put it there at all?

... SubClass 构造函数中的第一个参数是做什么用的?它没有被分配或用于我的派生类的任何方法中。为什么我必须把它放在那里?

采纳答案by Servy

As to why you can't do:

至于为什么你不能这样做:

public SubClass(string SubString) : base(BaseString)

What would BaseStringbe?

BaseString是什么?

You could do:

你可以这样做:

public SubClass(string SubString) : base("SomeFixedString")

or

或者

public SubClass(string SubString) : base(SubString)

But if you want to pass one string to the base class constructor's parameter and have an additional one, you'll need to accept two parameters.

但是,如果您想将一个字符串传递给基类构造函数的参数并有一个额外的字符串,则需要接受两个参数。

As to keeping the same name, you don't. You could do:

至于保持相同的名字,你没有。你可以这样做:

public SubClass(string AnotherString, string SubString) : base(AnotherString)

As to the last question, the first parameter isn't doing nothing, it's being passed to the base class constructor. You could use it for something else if you wanted to.

关于最后一个问题,第一个参数不是什么都不做,它被传递给基类构造函数。如果您愿意,您可以将其用于其他用途。

回答by Sergey Berezovskiy

If you want to initialize BaseStringwith default value, then pass that value to base class constructor (thus you don't have to pass that parameter to derived class constructor)

如果要BaseString使用默认值初始化,则将该值传递给基类构造函数(因此您不必将该参数传递给派生类构造函数)

public SubClass(string SubString) : base(null)

Or define parameterless constructor in base class.

或者在基类中定义无参数构造函数。

Also about parameter naming - it does not matter what name has parameter, which you are passing to derived constructor. The only thing which matter is a value you are passing to base constructor.

还有关于参数命名 - 什么名称具有参数并不重要,您将其传递给派生构造函数。唯一重要的是传递给基本构造函数的值。

public SubClass(string AnotherString, string SubString) : base(AnotherString)

回答by xbonez

public SubClass(string BaseString, string SubString) : base(BaseString)

This constructor in the derived class says that when you receive two arguments BaseStringand SubString, call the base class's constructor with BaseString.

派生类中的这个构造函数表示,当您收到两个参数BaseStringand 时SubString,用 调用基类的构造函数BaseString

Thus, doing

因此,做

public SubClass(string a, string b) : base(BaseString)

doesn't work, because you are telling it to call the base class's constructor with BaseStringbut there is no argument called BaseString.

不起作用,因为您告诉它调用基类的构造函数 withBaseString但没有调用BaseString.

If you want to instantiate the derived class without passing a String to the base class constructor, the base class needs a default constructor:

如果要实例化派生类而不将 String 传递给基类构造函数,则基类需要一个默认构造函数:

public BaseClass() { }

回答by ose

If you want to provide the opportunity for the derived class NOT to set the BaseString, then you need to provide a default constructor in the base class like this:

如果您想为派生类提供不设置 BaseString 的机会,那么您需要在基类中提供一个默认构造函数,如下所示:

public BaseClass()
{

}

Now in the derived class, you can call the constructor with no arguments in the base class like this:

现在在派生类中,您可以像这样在基类中调用没有参数的构造函数:

public SubClass(string AnotherString)
     : base()
{
    // base() => explicit call to default construct in the base class.
    // Do something else
}

This provides good software engineering practice: if you want to provide the opportunity not to set the base class's string, then do so in the base class. Other 'hacks' like passing null as an argument to the base constructor only serve to tinker with the base class's internals in ways that should not be done from subclasses.

这提供了良好的软件工程实践:如果您想提供不设置基类字符串的机会,请在基类中设置。其他“技巧”,例如将 null 作为参数传递给基本构造函数,只会以不应从子类中完成的方式修补基类的内部结构。