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构造函数的第一个参数是什么?它没有在我的派生类的任何方法中分配或使用。为什么我甚至要把它放在那里呢?
答案 0 :(得分:21)
至于为什么你不能这样做:
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)
关于最后一个问题,第一个参数没有做任何事情,它被传递给基类构造函数。如果你愿意的话,你可以把它用在别的东西上。
答案 1 :(得分:3)
如果你想为派生类提供机会不设置BaseString,那么你需要在基类中提供一个默认构造函数,如下所示:
public BaseClass()
{
}
现在在派生类中,您可以在基类中调用没有参数的构造函数,如下所示:
public SubClass(string AnotherString)
: base()
{
// base() => explicit call to default construct in the base class.
// Do something else
}
这提供了良好的软件工程实践:如果您想提供不设置基类字符串的机会,那么在基类中执行此操作。其他' hacks'比如将null作为参数传递给基础构造函数只是用来修改基类的内部,而这种方式不应该从子类中完成。
答案 2 :(得分: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() { }
答案 3 :(得分:1)
如果要使用默认值初始化BaseString
,则将该值传递给基类构造函数(因此您不必将该参数传递给派生类构造函数)
public SubClass(string SubString) : base(null)
或者在基类中定义无参数构造函数。
关于参数命名 - 无论什么名称都有参数,你传递给派生构造函数。唯一重要的是你传递给基础构造函数的值。
public SubClass(string AnotherString, string SubString) : base(AnotherString)