2

如果一个类从两个单独的接口实现一个接口,它的行为是否与它只实现一次一样?

例子:

public interface IAnimal { /* ... */ }
public interface IFullAnimal : IAnimal { /* ... */ }

public interface IBear : IAnimal { /* ... */ }
public interface IFullBear : IBear, IFullAnimal { /* ... */ }

// and implementing IFullBear:
public class FullBear : IFullBear { /* ... */ }

上面,从两者和通过FullBear实现。这是否会引入有关 IAnimal 实现的任何奇怪行为,因为两者没有提供有关实现的任何信息(因为语言不允许这样做)。IAnimalIFullAnimalIBearIFullBearIFullAnimalIBearIAnimal

4

2 回答 2

4

在 .NET 中,如果IAIB都继承自并且类实现了两者,则“被继承者”的成员和“被继承者”的IX成员之间没有区别。所有这些成员都只是. 此外,声明为实现、和的类与仅声明为实现和的类之间没有区别,因为任何实现 、 或两者的类都必然也实现,无论它是否被声明这样做。IXIAIXIBIXIAIBIXIAIBIAIBIX

.NET 接口继承模型避免了“钻石问题”,因为中级接口无法向继承的接口添加任何东西,从而将它们与这些相同接口的任何其他继承版本区分开来。Java 的模型过去也避免了菱形问题,但是通过允许中级接口声明默认方法,Java 的更高版本使致命的菱形层次结构成为可能。

于 2017-11-09T19:50:42.780 回答
3

不,这是一种非常常见且无害的情况。System.Collections.Generic命名空间是类似“冗余”接口声明的一个很好的例子:

 public class List<T> : IList<T>, 
                        System.Collections.IList,
                        IReadOnlyList<T>

两者显然都实施了IList<T>,世界还没有结束。IReadOnlyList<T>IEnumerable<T>

不要将此与interface reimplementation混淆,后者确实会改变行为:

interface IFoo
{
    void Foo();
}

class Base: IFoo
{
     public void Foo() { Console.WriteLine("Base Foo!");
}

class Derived: Base { }

class DerivedWithATwist: Base, IFoo //redeclares interface
{
    void IFoo.Foo() { Console.WriteLine("Derived Foo!");
}

现在,

IFoo foo = new Base();
IFoo derived = new Derived();
IFoo derivedWithATwist = new DerivedWithATwist();

foo.Foo(); //Base Foo!
derived.Foo(); //Base Foo!
derivedWithATwist.Foo(); //Derived Foo!
(derivedWithATwist as Base).Foo(); //Base Foo!  !!!
于 2017-11-09T20:46:05.393 回答