从D中的子类调用重载的父方法

问题描述 投票:0回答:2

假设我有以下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)
一样,但这看起来很尴尬。

这是语言中的错误吗?或者有没有更好的重载方法来继承?

inheritance d
2个回答
3
投票

您需要使用 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 中使用类似的别名声明。


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);
}
© www.soinside.com 2019 - 2024. All rights reserved.