简化方案。三个分支,GrandParent,父母和孩子。我想要做的是使用GrandParent和Parent构造函数来初始化Child实例。
class GrandParent ()
{
public int A {get; protected set;}
public int B {get; protected set;}
public GrandParent (int a, int b);
{
A = a;
B = b;
}
}
class Parent : GrandParent ()
{
public Parent () {}
}
Child Class,问题出现了。
class Child : Parent ()
{
public int C {get; protected set}
public Child (int c) // here I want it to also call the GrandParent (int a, int b)
// before calling Child (int c)
{
C = c;
}
}
Child = new Child (1,2,3);
我想要的是变量a,b和c分别得到1,2作为值。我知道只需将A = a
和B = b
添加到Child
构造函数即可解决此问题。
这可能吗?如果是这样的话?
我开始查看base(),但看起来它只能访问Parent
类,而不是GrandParent
。
提前致谢。
PS。如果之前有人问过,我提前道歉,我什么都没找到。
快速编辑:我正在努力使解决方案尽可能简单,以便进一步发展。
答案 0 :(得分:4)
您只能将构造函数调用到直接超类。直接超类需要公开您需要的选项。它可以使用protected
构造函数安全地执行此操作。
答案 1 :(得分:1)
C#良好实践假定您在每个子进程中调用基类构造函数。也就是说,你将从父母和基地(a,b)调用基地(a,b)来自孩子,这将调用祖父母ctor。这让你无法接受。这是你的代码片段重写:
class GrandParent ()
{
public int A {get; protected set;}
public int B {get; protected set;}
public GrandParent (int a, int b);
{
A = a;
B = b;
}
}
class Parent : GrandParent ()
{
public Parent (int a, int b):base(a,b) {}
}
Child Class, were the problem occurs.
class Child : Parent ()
{
public int C {get; protected set}
public Child (int a, int b, int c):base(a,b)
{
C = c;
}
}
答案 2 :(得分:1)
您需要将变量通过每个构造函数传递给它的基础构造函数:
class Child : Parent ()
{
public int C {get; protected set}
public Child (int a, int b, int c) : base(a,b)
// before calling Child (int c)
{
C = c;
}
}
Child = new Child (1,2,3);
class GrandParent ()
{
public int A {get; protected set;}
public int B {get; protected set;}
public GrandParent (int a, int b);
{
A = a;
B = b;
}
}
class Parent : GrandParent ()
{
public Parent (int a, int b) : base(a,b) {}
}
答案 3 :(得分:1)
父和孩子是有限适用性的类比,因为派生类不是基础的“孩子”,因为人或动物的孩子是儿童的它们,甚至作为子目录是树中的目录或从属节点(GUI或数据结构)。
这种关系实际上是对于下位词的上位词。遗憾的是, hypernym 并不像 parent 那样众所周知,因此人们经常使用不太准确的父来解释继承而不是上位词
现在,让我们考虑第一类声明:
class GrandParent
{
public int A {get; protected set;}
public int B {get; protected set;}
public GrandParent (int a, int b)
{
A = a;
B = b;
}
}
这与问题完全相同,只是第一行的错误()
和第六行的;
已删除。
它有一个构造函数,需要两个整数。
这意味着:
GrandParent
没有逻辑意义。当我们来到Parent
:
class Parent : GrandParent
{
public Parent () {}
}
这里我修复了语法错误,但没有别的。
由于构造函数中没有明确使用base
,因此隐含调用无参数base()
。也就是说,上述内容完全相同:
class Parent : GrandParent
{
public Parent()
: base()
{
}
}
对new Parent()
的任何来电都将通过base()
来电new GrandParent()
。由于GrandParent()
上没有无参数构造函数,因此无法编译。
这里的语言规则正在帮助我们:
GrandParent
是没有意义的。Parent
是一种GrandParent
。Parent
而没有设置这两个整数。我们说过三件事都是真的,但事实并非如此。语言规则是正确的,指出我们的错误。
要解决此问题,我们需要:
GrandParent
,而不在其构造中使用这两个整数。Parent
s总是在其构造中使用两个整数,然后依次使用基础构造函数。Parent
调用base(a, b)
上的无参数构造函数具有一些设定值。上面的第3个看起来像是:
class Parent : GrandParent
{
public Parent()
: base(42, -343213)
{
}
}
或者其他什么,只要这些数字来自某个地方(显然在真实的代码中,它们会与比我的随机输入更合理的东西相关)。
现在我们有一个Parent
实际上具有逻辑意义,其余的可以遵循。