D语言子类调用重载父类方法遇编译错误,求合理解决方案
D语言子类重载方法遮蔽父类同名方法的问题解决
这不是D语言的bug,而是它的名称遮蔽规则导致的:只要子类定义了和父类同名的方法(哪怕参数列表不一样),编译器就会优先使用子类的方法,同时把父类所有同名的其他重载版本都“遮蔽”掉。所以Child类里的print(string s)会把父类的print(int x)藏起来,直接用Child类型对象调用print(5)时,编译器只会在子类的方法里找匹配项,自然找不到int版本的实现。
几种优雅的解决方案
1. 引入父类的同名方法到子类
在Child类中添加alias Parent.print this;,这会把父类所有print方法都引入到子类的名称空间里,编译器就能找到int版本的方法了:
class Child : Parent { alias Parent.print this; // 引入父类所有print重载 override void print(string s) { import std.stdio : writeln; writeln(s); } }
2. 显式转发特定重载方法
如果只需要引入父类的某个特定重载版本,可以在子类里显式转发:
class Child : Parent { override void print(string s) { import std.stdio : writeln; writeln(s); } // 转发父类的int版本print void print(int x) { super.print(x); } }
3. 使用父类类型声明变量
如果业务场景允许,直接把Child对象声明为Parent类型,编译器会自动在父类的方法集合中查找匹配的重载:
unittest { Parent c = new Child(); c.print(5); // 正常调用父类的print(int) c.print("hello"); // 调用子类的override方法 }
这种名称遮蔽规则是D语言的设计选择,目的是避免意外调用父类方法引发的潜在问题,用上面的方法就能替代繁琐的强制类型转换,更优雅地解决问题。
内容的提问来源于stack exchange,提问作者Andrew Lalis
相关产品推荐
相关产品推荐

