Should one interface inherit another interface

71,413

Solution 1

Interface inheritance is an excellent tool, though you should only use it when interface B is truly substitutable for interface A, not just to aggregate loosely-related behaviors.

It's difficult to tell whether it is appropriate for your specific case, but there's nothing wrong using the practice in principle. You see it in the first-rate APIs all the time. To pick just one common example, from the .NET framework:

public interface ICollection<T> : IEnumerable<T>, IEnumerable

Solution 2

Consider whether the interfaces should be logically paired, and if you feel that they work well with each other then absolutely use inheritance.

Lets look at an example;

public interface IScanner
{
    void Scan();
}

public interface IPrinter
{
    void Print();
}

Printers and scanners are often separate objects, each with their own functionality however these two devices are often paired in the same device;

public interface IPhotocopier : IScanner, IPrinter
{
    void Copy();
}

It makes sense that IPhotocopier should inherit from IScanner and IPrinter as this now allows the photocopier to be used as either a scanner or printer (which it contains) in addition to its primary roll as a copier.

Now lets look at one more interface;

public interface IBlender
{
    void Blend();
}

It would not make sense to allow IBlender to be inherited by any of the earlier interfaces (what would you call them? IBlendingScanner?).

If you can't give your new interface a sensible name this might indicate that your may not want to use inheritance in this instance.

It's a bad idea to inherit some interfaces such as IDisposable, since this forces all implementations of your new interface to implement the dispose pattern even if they do not have any disposable resources.

Solution 3

Technically speaking, interfaces don't inherit from each other. What really happens when you create an IFoo that inherits from IBar, you're saying that any class that implements IFoo must also implement IBar.

interface IBar
{
    void DoBar();
}

interface IFoo : IBar
{
    void DoFoo();
}

In this example, the IFoo interface does not have a DoBar() method. Most of the time the distinction doesn't matter, but it can bite you when using reflection on an interface rather than a class.

Solution 4

It is certainly possible to have an inheritance tree of interfaces, and even "multiple inheritance" with interfaces. Whether it is the right thing to do or not depends on the interfaces in question. If it really is the case that interface B is an extension or refinement of interface A, then inheritance makes sense, but if the new enum is largely unrelated to the concept expressed by interface A, I would make them two separate interfaces and have the classes that need to implement both interfaces.

Solution 5

I think databases always provide a great way to demonstrate interfaces, so considering if an interface should inherit another interface look at the following,

IMySqlDatabase : IDatabase
MySqlDatabase : IMySqlDatabase

IMsSqlDatabase : IDatabase
MsSqlDatabase : IMsSqlDatabase

A MySqlDatabase IS an IMySqlDatabase and an IMySqlDatabase IS an IDatabase.

Now if you need to make changes to your IDatabase interface it's grandchildren (the conrete database classes) can reap the benefits, but you won't have to expand MySQL AND MsSQL (or perhaps even more DBMS' Interfaces). At the same time in your middle man (IMsSqlDatabase) you can still have interface features that a MySQL or Oracle DB wouldn't support.

Share:
71,413

Related videos on Youtube

ajrawson
Author by

ajrawson

.net developer working mostly with asp.net MVC at the moment. But also spending some time maintaining classic asp and web forms applications as well.

Updated on April 19, 2021

Comments

  • ajrawson
    ajrawson about 3 years

    I can't seem to find an answer on this and just want to make sure it's an ok coding standard. I have interface A that is used by many different classes and don't want interface A to change. I came across a new requirement that will require an enum to be needed by many of the classes that implement Interface A, but not all the classes need this enum. I don't want the classes that don't require this new enum to implement this new functionality. So I created interface B that contains the new enum that I needed to add. I then made interface B inherit interface A and this is my concern, Is it ok for one interface to Inherit another interface? To continue with my changes, I then changed the classes that needed the new enum to implement interface B instead of interface A since it was inherited by interface B. I thought about implementing both interfaces in my classes that needed them but I'm using the interface throughout the code and would like to just use one interface for looking through classes and not two.

    I hope this was clear enough (probably too long) but if anyone can give me some advice on this either I'm doing it right or I'm doing it wrong please let me know.

    Thanks!

  • Jeff Sternal
    Jeff Sternal over 14 years
    Even given the behavior you've described (described in excellent detail in Phil Haack's recent column, haacked.com/archive/2009/11/10/…), I think it's unduly confusing to say 'interfaces don't inherit from each other' in C# when the C# reference documentation even uses that terminology, as in "An interface can inherit from one or more base interfaces." (msdn.microsoft.com/en-us/library/87d83y5b%28VS.80%29.aspx) I'd prefer just to say that, in C#, interface inheritance behaves differently than class inheritance when reflecting inherited members.
  • Joel Mueller
    Joel Mueller over 14 years
    Fair enough. I guess it depends on how "inherit" is defined. Certainly the C# syntax is the same whether it's classes or interfaces. But if you think of inheritance as including the members of the parent, then your mental model doesn't match reality when you're talking about interfaces.
  • Jeff Sternal
    Jeff Sternal over 14 years
    I originally suggested the Liskov substitution principle should apply. In retrospect, that isn't really relevant. Most of the requirements of the LSP (maintaining invariants, restrictions on pre- and post-conditions) are really only applicable to concrete implementations, not interfaces. Having said that, the general principle of substitutability should still guide interface inheritance decisions.
  • Chad Crowe
    Chad Crowe about 7 years
    Liskov substitution principle: It is important to make sure that interface B can completely replace interface A. Otherwise, you'll end up with functionality you have to implement that you don't want. This leads to extra code you don't want which makes software less stable.
  • DanCaveman
    DanCaveman over 5 years
    I have found it to work well when substituting a facade for an existing dependency that now needs a second implementation. Instead of changing the original class and all tests to need a factory, the facade handles using the factory and returning the desired result. I use marker interfaces to inject the two different interfaces into the factory the facade will use. Only the factory knows about the "marker" interfaces. Not ideal, but I like it better than changing the existing classes.
  • KevinVictor
    KevinVictor over 2 years
    Thanks for pointing this out. Didn't realize this was how it worked when dealing with reflection of interfaces.