假设我有以下D代码:
class Parent {
void print(int x) {
import std.stdio : writeln;
writeln(x);
}
abstract void print(string s);
}
class Child : Parent {
override void print(string s) {
import std.stdio : writeln;
writeln(s);
}
}
unittest {
Child c = new Child();
c.print(5);
}
当我编译此代码时,我收到一个编译器错误,指出
function Child.print(string s) is not callable using argument types (int)
这很令人困惑,因为我希望在对子级调用它时,会调用父级的
print(int x)
方法。我可以解决这个内联转换,就像(cast(Parent)c).print(5)
一样,但这看起来很尴尬。
这是语言中的错误吗?或者有没有更好的重载方法来继承?
您需要使用 Parent.print 的别名来修改 Child:
class Child : Parent {
alias print = Parent.print;
override void print(string s) {
import std.stdio : writeln;
writeln(s);
}
}
这是故意的。这是为了防止功能劫持。你可以在这里读到它: https://dlang.org/articles/hijack.html
“派生类成员函数劫持”部分的相关文本:
C++ 的想法是正确的,派生类中的函数隐藏 基类中的所有同名函数,即使 基类中的函数可能更匹配。 D 遵循此 规则。再一次,如果用户希望它们超载 相互对抗,这可以在 C++ 中通过使用来完成 声明,并在 D 中使用类似的别名声明。
“问题”出在超载...
以下代码可以工作,因为它避免了“print”方法的重载:
class Parent {
void printInt(int x) {
import std.stdio : writeln;
writeln(x);
}
abstract void printString(string s);
}
class Child : Parent {
override void printString(string s) {
import std.stdio : writeln;
writeln(s);
}
}
void main() {
Child c = new Child();
c.printInt(5);
}
如果你真的想重载 print() 方法,那么你的 Child 中应该有类似
override void print(int x) { super.print(x); }
的东西:
class Parent {
void print(int x) {
import std.stdio : writeln;
writeln(x);
}
abstract void print(string s);
}
class Child : Parent {
override void print(int x) { super.print(x); }
override void print(string s) {
import std.stdio : writeln;
writeln(s);
}
}
void main() {
Child c = new Child();
c.print(5);
}