英文:
Calling overloaded parent methods from child class in D
问题
假设我有以下的 D 代码:
类 父类 {
void 打印(int x) {
导入 std.stdio : writeln;
writeln(x);
}
抽象 void 打印(string s);
}
类 子类 : 父类 {
重写 void 打印(string s) {
导入 std.stdio : writeln;
writeln(s);
}
}
单元测试 {
子类 c = 新 子类();
c.打印(5);
}
当我编译这段代码时,我收到一个编译器错误,指出
函数 子类.打印(string s) 无法使用参数类型 (int) 进行调用
这让我感到困惑,因为我期望调用子类时会调用父类的 打印(int x)
方法。我可以通过内联转换解决这个问题,比如 (cast(父类)c).打印(5)
,但这看起来很别扭。
这是语言的一个错误吗?还是有更好的继承和重载方法的方法?
英文:
Suppose I have the following D code:
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);
}
When I compile this code, I get a compiler error stating that
function Child.print(string s) is not callable using argument types (int)
This is confusing, because I would expect that the parent's print(int x)
method would be invoked when calling it on the child. I can solve this casting inline, like (cast(Parent)c).print(5)
, but this seems awkward.
Is this a bug in the language? Or is there a better approach to inheritance with overloaded methods?
答案1
得分: 3
你需要修改 Child 类并使用别名来引用 Parent.print:
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++ 中使用 using 声明,在 D 中使用类似的 alias 声明来实现。
英文:
You'll need to modify Child with an alias to Parent.print:
class Child : Parent {
alias print = Parent.print;
override void print(string s) {
import std.stdio : writeln;
writeln(s);
}
}
This is intentional. It's to prevent function hijacking. You can read about it here:
https://dlang.org/articles/hijack.html
The relevant text from the section 'Derived Class Member Function Hijacking':
> C++ has the right idea here in that functions in a derived class hide
> all the functions of the same name in a base class, even if the
> functions in the base class might be a better match. D follows this
> rule. And once again, if the user desires them to be overloaded
> against each other, this can be accomplished in C++ with a using
> declaration, and in D with an analogous alias declaration.
答案2
得分: 1
"问题"出在重载...
以下代码将起作用,因为它避免了对 "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);
}
英文:
"Problem" is in the overloading...
The following code will work because it avoids overloading of the "print" method:
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);
}
If you really do want to overload the print() method, then you should have something like override void print(int x) { super.print(x); }
in your Child:
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);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论