[疑难] d如何处理同名的接口函数
yntcsb
2009-05-14
假如我有一个IA接口和一个IB接口,碰巧里边都声明了一个 void Show ()函数,现在我用一个类ABC同时继承这两个接口,那么在类ABC中如何实现这个完全相同Show函数呢?D语言里不支持如下的显式实现接口
module inter; import tango.io.Stdout; interface IA { void Show(); } interface IB { void Show(); } class ABC : IA,IB { void IA.Show() { Stdout("Show me,IA").newline; } void IB.Show() { Stdout("Show me,IB").newline; } } void main() { IA ia = new ABC(); ia.Show(); IB ib = new ABC(); ib.Show(); } 如上代码,编译将报错。 module inter; import tango.io.Stdout; interface IA { void Show(); } interface IB { void Show(); } class ABC : IA,IB { void Show() { Stdout("Show me").newline; } } void main() { IA ia = new ABC(); ia.Show(); IB ib = new ABC(); ib.Show(); ABC abc = new ABC(); abc.Show(); } 这样的代码成功编译,但类ABC中的Show实现的是IA的,还是IB的,不是很清楚。特别是类ABC的对象abc调用的Show属于哪个接口的不清楚。 |
|
Sam1860
2009-05-14
show()不属于IA,IB的,是属于ABC的,只有类才会有实现,接口没有实现。只是ABC满足了IA, IB的约定,别人可以把ABC当IA,IB调而已。
就如猫,本身是客观存在“吃”这个功能,不管你叫它“猫"好,还是叫它“动物”也好 |
|
Sam1860
2009-05-15
如果你是想被当作IA和IB时调用该方法的处理不一样(如用了两个库刚好遇到这种情况)最好还是改一下自己的设计,实现两个类吧
|
|
dogstar
2009-05-15
接口是契约,相当于你要实现两份契约,都要求你晚上睡觉要刷牙,那你刷一次就能满足两份契约了.没必要刷两次吧.
|
|
d2008
2009-05-15
在现实中是有必要满足两份同名契约的!
现举例如下: interface 接口猫{ void 走路(); } interface 接口人{ void 走路(); } class 孙悟空 : 接口猫, 接口人{ void 接口猫.走路(){ 输出("猫,是用4条腿走路的"); } void 接口人.走路(){ 输出("人,是用2条腿走路的"); } void 走路(){ 输出("老孙我可以变成猫,用4条腿走路;也可以变成人,用2条腿走路。"); } } void main(){ 孙悟空 悟空 = new 孙悟空(); 悟空.走路(); 接口猫 猫 = 悟空; //悟空变猫 猫.走路(); 接口人 人 = 悟空; //悟空变人 人.走路(); } 同样是走路(),但在不同的接口也应有不同的解释。在C#中可以用类似上面的的代码,对具体接口中的方法进 行单独实现,而D却不能。不能不说这是D的一个缺陷。 (在C#中,不但可以向下由子类实现多态,也可以向上由接口实现多态!) |
|
ideage
2009-05-16
还真是自己折磨自己.呵呵
|
|
Sam1860
2009-05-16
我觉得d2008举的例子是不合适的。
孙悟空 悟空 = new 孙悟空(); 悟空.走路(); 接口猫 猫 = 悟空; //悟空变猫 这里不是说你管悟空叫猫或加个注释悟空就变猫了,悟空还是悟空,在这里他没有72变(起码在你这个例子里),他有自己固有的走路方式,是不以你(调用者)的意志改变的 C#提供的这种方式根本不是为了OO,而是为了处理遇到的某些不得已方法名冲突而已(别人提供的接口)。根本就应该不用为妙的 我一点都不觉得这是D的缺陷 |
|
Sam1860
2009-05-16
大家是否觉得这样才叫OO呢?
interface 会走的 { 走() } interface 形态: 会走的{ } class 猴子:形态 { 走() { // 猴子走 } } class 猫:形态 { 走() { // 猫走 } } class 悟空: 会走的 { 形态 xt; 走(){ xt.走() }; 变猫(){ xt = new 猫()} 边猴(){ xt = new 猴()} } |
|
d2008
2009-05-16
可能如你所说的那样,C#的提供对具体接口可单独实现的功能,
是为了解决遇到的同名函数的问题,而不是实现oop概念中的多态(也应该不可能这 样实现的)。 但是,在D中却没有在语言层面上提供这样的支持,只能由开发者在类的设计上作更 改,不能不说是一个缺陷。至少现在我是这样理解的,应为我没找到在一个类上实 现不同接口同名函数的可行方法。 我曾这样思考过: interface IA{ void F(); } interface IB{ void F(); } interface IAA:IA { alias IA.F FA; } interface IBB:IB { alias IB.F FB; } class C: IAA, IBB{ void FA(){ } void FB(){ } } 但发现 alias 的作用只能是一个别名,根本没法取代原来正真的函数名! 第二种方式是RTTI interface IA{ void F(); } interface IB{ void F(); } class C: IAA, IBB{ void F(){ if( 当前运行类型 == typeid(C) ) { } else if( 当前运行类型 == typeid(IA) ) { /**针对IA.F实现**/ } else if( 当前运行类型 == typeid(IB) ) { /**针对IB.F实现**/ } } } 但在D中怎么获得当前运行类型呢?又找不到答案! 还请D的各位fans,指点解惑! |
|
sweet
2009-05-18
|