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?
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.