28

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

首先是基类:

class BaseClass
{
    private string BaseOutput = null;

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

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

这是派生类:

class SubClass : BaseClass
{
    private string SubOutput = null;

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

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

最后,程序的主要部分:

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();
    }
}

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

public SubClass(string SubString) : base(BaseString)

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

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

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

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

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

4

4 回答 4

29

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

public SubClass(string SubString) : base(BaseString)

BaseString是什么?

你可以这样做:

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

或者

public SubClass(string SubString) : base(SubString)

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

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

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

至于最后一个问题,第一个参数没有做任何事情,它被传递给基类构造函数。如果您愿意,可以将其用于其他用途。

于 2012-11-23T23:52:48.220 回答
5

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

public BaseClass()
{

}

现在在派生类中,您可以在基类中调用不带参数的构造函数,如下所示:

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

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

于 2012-11-23T23:52:50.913 回答
2
public SubClass(string BaseString, string SubString) : base(BaseString)

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

因此,做

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

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

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

public BaseClass() { }
于 2012-11-23T23:52:21.327 回答
1

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

public SubClass(string SubString) : base(null)

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

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

public SubClass(string AnotherString, string SubString) : base(AnotherString)
于 2012-11-23T23:52:01.730 回答