派生 class 中的无意基础 class 构造函数 "hiding"
Inadvertent base class constructor "hiding" in derived class
[注意:编写代码只是为了显示问题,而不是因为它本身就有用。]
假设我有两个 classes,A
和 B
:
public class A {
public const int max = 2;
public int[] id;
public A() {
this.id = new int[A.max];
}
public A(int id) : this() {
this.id[0] = id;
}
public A(int id, int id2) : this() {
this.id[0] = id;
this.id[1] = id2;
}
}
public class B : A {
public B(int[] ids) : base() {
int x = 0;
while ( ( x < ids.Length ) && ( x < A.max ) ) {
this.id[x] = ids[x];
x++;
}
}
}
看来,通过在 B
中创建新的构造函数,我无意中隐藏了 A
中 B
通常 "inherited" 的所有构造函数(事实上,我了解到构造函数在 C# 中不是继承的,但我在这里仍然感到困惑)。
例如:
A first = new A(); // fine
int[] x = new int[A.max-1];
B second = new B(x); // fine
B third = new B(12); // nope
如果我从 B
中删除新的构造函数,那么 B third = new B(12);
就可以正常工作(在我的术语中,构造函数不再是 "hidden")。但是随着 B
中的新构造函数,我不再可以使用 A(int)
构造函数。
那么 REALLY 的解决方案是简单地重新定义 ALL 我希望 B 从 A 继承并使它们为空的构造函数吗?示例:
public class B : A {
public B(int id) : base(id) {} // adding this!
public B(int[] ids) : base() {
int x = 0;
while ( ( x < ids.Length ) && ( x < A.max ) ) {
this.id[x] = ids[x];
}
}
}
如果我进行更改,现在 B third = new B(12);
就可以正常工作了。但是我必须重新定义我想在派生 class 的基础 class 中使用的每个构造函数,这似乎有点难看,仅仅是因为我要向那个派生 class 添加一个新的构造函数]!
是的,派生 class 不会从基 class 获取或公开构造函数。您需要在 base class 中定义所有必要的构造函数(可能调用 base class' 构造函数)。
注意:如果您派生的 class 没有任何要初始化的东西,您可能需要重新考虑是否真的需要新的 class。
我认为 EleventyOne 完全正确,您的示例很笨拙,但问题不在于语言,而在于您的设计。我知道你的例子不是真实世界的例子,因此抽象的问题会产生抽象的答案。
如果您发现自己的基础上有很多构造函数 class 很可能您的设计是错误的。可能你正在尝试在继承中建模更适合组合的东西,或者你的基础 class 应该接受一个对象而不是单独的相关属性,如果这些属性不相关那么也许你的基础 class 做得太多了(单一职责原则)。
当感觉不对时,很可能是您有代码味! :)
[注意:编写代码只是为了显示问题,而不是因为它本身就有用。]
假设我有两个 classes,A
和 B
:
public class A {
public const int max = 2;
public int[] id;
public A() {
this.id = new int[A.max];
}
public A(int id) : this() {
this.id[0] = id;
}
public A(int id, int id2) : this() {
this.id[0] = id;
this.id[1] = id2;
}
}
public class B : A {
public B(int[] ids) : base() {
int x = 0;
while ( ( x < ids.Length ) && ( x < A.max ) ) {
this.id[x] = ids[x];
x++;
}
}
}
看来,通过在 B
中创建新的构造函数,我无意中隐藏了 A
中 B
通常 "inherited" 的所有构造函数(事实上,我了解到构造函数在 C# 中不是继承的,但我在这里仍然感到困惑)。
例如:
A first = new A(); // fine
int[] x = new int[A.max-1];
B second = new B(x); // fine
B third = new B(12); // nope
如果我从 B
中删除新的构造函数,那么 B third = new B(12);
就可以正常工作(在我的术语中,构造函数不再是 "hidden")。但是随着 B
中的新构造函数,我不再可以使用 A(int)
构造函数。
那么 REALLY 的解决方案是简单地重新定义 ALL 我希望 B 从 A 继承并使它们为空的构造函数吗?示例:
public class B : A {
public B(int id) : base(id) {} // adding this!
public B(int[] ids) : base() {
int x = 0;
while ( ( x < ids.Length ) && ( x < A.max ) ) {
this.id[x] = ids[x];
}
}
}
如果我进行更改,现在 B third = new B(12);
就可以正常工作了。但是我必须重新定义我想在派生 class 的基础 class 中使用的每个构造函数,这似乎有点难看,仅仅是因为我要向那个派生 class 添加一个新的构造函数]!
是的,派生 class 不会从基 class 获取或公开构造函数。您需要在 base class 中定义所有必要的构造函数(可能调用 base class' 构造函数)。
注意:如果您派生的 class 没有任何要初始化的东西,您可能需要重新考虑是否真的需要新的 class。
我认为 EleventyOne 完全正确,您的示例很笨拙,但问题不在于语言,而在于您的设计。我知道你的例子不是真实世界的例子,因此抽象的问题会产生抽象的答案。
如果您发现自己的基础上有很多构造函数 class 很可能您的设计是错误的。可能你正在尝试在继承中建模更适合组合的东西,或者你的基础 class 应该接受一个对象而不是单独的相关属性,如果这些属性不相关那么也许你的基础 class 做得太多了(单一职责原则)。
当感觉不对时,很可能是您有代码味! :)