7

从具有未使用方法的类继承是否违反了接口隔离原则?

例如:

abstract class Base
{
    public void Receive(int n)
    {
        // . . . (some important work)

        OnMsg(n.ToString());
    }

    protected abstract void OnMsg(string msg);
}

class Concrete : Base
{
    protected override void OnMsg(string msg)
    {
        Console.WriteLine("Msg: " + msg);
    }
}

Concrete取决于 method Base.Receive(int n),但它从不使用它。

UPD

我使用的定义:

ISP 声明不应强迫任何客户端依赖它不使用的方法。

4

2 回答 2

10

我认为您误解了接口隔离原则所说的内容。在您的情况下,您很好,并且没有“强制”任何实施。实际上,您正在应用模板方法设计模式

如果你有一个假设

interface ICommunicateInt
{
  int Receive();
  void Send(int n);
}

为了实现它,您的Base类将被迫实现Send它不需要的方法。因此,ISP 建议最好有:

interface ISendInt
{
  void Send(int n);
}

interface IReceiveInt
{
  int Receive();
}

所以你的类可以选择实现一个或两个。其他类中需要可以发送 Int 的类的方法也可能需要

void Test(ISendInt snd)
// void Test(ICommunicateInt snd) // Test would "force" snd to depend on 
                                  // a method that it does not use 
于 2013-07-10T08:30:31.440 回答
0

我没有看到 Concrete 以我使用该术语的方式“依赖” Base.Receive() 。如果 Receive 被修改,Concrete 需要如何改变?我会争辩,一点也不。假设我们用不同名称或不同签名的方法替换了 Receive(),Concrete 将不知道。Concrete 是否调用 Receive()?不,所以我在这里看不到对 Receive() 的依赖。

依赖于签名 OnMsg(),Concrete 与 Base 有非常特殊的关系,履行 OnMsg() 合同。

但在另一种意义上,Concrete 非常依赖于 Base.Receive(),它是它与外界的接口——没有这种方法,任何人都无法访问 Concrete 的功能。在这个意义上,Concrete 在一个非常基础的层面上“使用”了 Base.Receive()。

于 2013-07-10T07:45:47.190 回答