interface ILeft : IBase ... { new void Add(int i); }
interface IRight : IBase ... { void G(); }
interface IDierived : ILeft , IRight ... { }
假设 n 是 IDierived的一个引用
n.Add( 1 ); // 正确,(如果ILeft不覆盖Add 则会产生了二义性)???<--问题
((IBase)n).Add( 1 ); // 调用IBase
((ILeft)n).Add( 1 ); // 调用ILeft
((IRight)n).Add( 1 ); // 调用IBase
// ------------------------------------------------------------------------------
以上的例子具体出处记不清了,网上也能找到类似的题目,以下是我对它的一些看法:
文中认为 一但ILeft接口去掉了 new ,就会导致 IDerived得到两条继承路径,从而导致二义性的产生.
但根据实际上机验证,就算ILeft没有覆盖Add,也不会产生二义性,这就是为什么C#里接口可以多重继承的原因了,
为了证明,可以 假设 :
class A : IDierived
... {
//实现覆盖的新成员()
void ILeft.Add(int i)
...{
Console.WriteLine("In ILeft.Add");
}
//实现原IBase的接口成员
public void IBase.Add(int i)
...{
Console.WriteLine("In Add");
}
//IRight接口的成员
public void G()
...{
}
}
或者你可以只用一个成员同时隐式的实现 ILeft与IBase接口的成员 Add
... {
//同时实现IBase接口的Add与ILeft接口的新成员Add
public void Add(int i)
...{
//具体代码
}
public void G()
...{
}
}
所以我们知道了, A类中的Add都是用来实现IBase的,所以不会存在有两个继承的路径
----------------------------------------------------------------------------------------------------------------------------
所以没有new 不会产生二义性,好了,那有new会不会就会产生二义性呢?
答案仍然不会,因为ILeft中 new会形成覆盖,虽然有两个"Add",方法,但是实现仍是分开实现,且
//假设 n 是 IDierived的一个引用
n.Add(1); //正确,
调用的将是 ILeft中的Add成员,就像IBase被阻隔一样,
这样,如果仍想访问IBase接口的成员时,只需显式的转换为IBase的引用即可
-------------------------------------------------------------------------------------------------------------------------------
只有最后一种情况: ILeft与IRight接口均覆盖了IBase的Add方法
这时,必定会产生二义性,因为我们只需记住:
覆盖后的方法与覆盖前的方法无关,故,会形成两个同名的独立方法在ILeft与IRight中,自然,
//假设 n 是 IDierived的一个引用
n.Add(1); //错误,无法确定调用哪个实现