[疑难] 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
Global site tag (gtag.js) - Google Analytics