質問

Does inheritance from a class with unused methods violates the interface segregation principle?

For example:

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 depends on method Base.Receive(int n), but it never uses it.

UPD

Definition I use:

ISP states that no client should be forced to depend on methods it does not use.

役に立ちましたか?

解決

I think you're misinterpreting what the interface segregation principle says. In your case you're fine and are not "forcing" any implementation. In fact you're applying the Template method design pattern

If you had a hypothetical

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

in order to implement it, your Base class would be forced to implement a Send method that it does not need. So, the ISP suggests that it is better to have:

interface ISendInt
{
  void Send(int n);
}

interface IReceiveInt
{
  int Receive();
}

so your classes can choose to implement one or both. Also methods in other classes that need a class that can send an Int, can require a

void Test(ISendInt snd)
// void Test(ICommunicateInt snd) // Test would "force" snd to depend on 
                                  // a method that it does not use 

他のヒント

I don't see that Concrete "depends" upon Base.Receive() in the way I would use the term. How would Concrete need to change if Receive were modified? I would argue, not at all. Suppose we replaced Receive() with a method of a different name or with a different signature, Concrete would be unaware. Does Concrete call Receive()? No. So I see no dependency on Receive() here.

The dependency is with the signature OnMsg(), Concrete participates in very particular relationship with Base, fulfilling that OnMsg() contract.

But in a different sense Concrete very much depends on Base.Receive(), which is it's interface to the outside world - without that method no-one can access Concrete's capabilties. In this sense Concrete "uses" Base.Receive() at a very fundamental level.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top