Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Although this is a general question it is also specific to a problem I am currently experiencing. I currently have an interface specified in my solution called

public interface IContextProvider
{
   IDataContext { get; set; }
   IAreaContext { get; set; }
}

This interface is often used throughout the program and hence I have easy access to the objects I need. However at a fairly low level of a part of my program I need access to another class that will use IAreaContext and perform some operations off it. So I have created another factory interface to do this creation called:

public interface IEventContextFactory 
{
   IEventContext CreateEventContext(int eventId);
}

I have a class that implements the IContextProvider and is injected using NinJect. The problem I have is that the area where I need to use this IEventContextFactory has access to the IContextProvider only and itself uses another class which will need this new interface. I don't want to have to instantiate this implementation of IEventContextFactory at the low level and would rather work with the IEventContextFactory interface throughout. However I also don't want to have to inject another parameter through the constructors just to have it passed through to the class that needs it i.e.

// example of problem
public class MyClass
{
    public MyClass(IContextProvider context, IEventContextFactory event)
    {
       _context = context;
       _event = event;
    }

    public void DoSomething() 
    {
       // the only place _event is used in the class is to pass it through
       var myClass = new MyChildClass(_event);
       myClass.PerformCalculation();      
    }
}

So my main question is, would this be acceptable or is it even common or good practice to do something like this (interface extend another an interface):

public interface IContextProvider : IEventContextFactory

or should I consider better alternatives to achieving what I need. If I have not provided enough information to give suggestions let me know and I can provide more.

share|improve this question
2  
I'd reword your question title as "Should interfaces inherit interfaces" since no interface actually implements anything. –  Jesse C. Slicer Sep 4 '12 at 20:52
    
@JesseC.Slicer ok thanks for that –  dreza Sep 4 '12 at 20:58
1  
The usual language is that an interface "extends" its parent, and (in doing so) "inherits" the methods of the parent interface, so I'd recommend using "extend" here. –  Theodore Murdock Sep 4 '12 at 22:02
    
Interfaces can extend parents, so why would it be bad practice? If an one interface is legitimately a super-set of another interface than of course it should extend it. –  Robin Winslow Sep 5 '12 at 9:07
    
feel free to accept one of the answers... –  Trevor Pilley Aug 23 '13 at 10:20
add comment

4 Answers 4

While interfaces describe only behavior without any implementation, they can still participate in inheritance hierarchies. As an example, imagine you have, say, the common idea of a Collection. This interface would provide a few things that are common to all collections, such as a method to iterate over the members. Then you can think about some more specific collections of objects such as a List or a Set. Each of these inherits all the behavior requirements of a Collection, but adds additional requirements specific to that particular type of collection.

Any time it makes sense to create an inheritance hierarchy for interfaces, then you should. If two interfaces will always be found together, then they should probably be merged.

share|improve this answer
add comment

Yes, but only if it makes sense. Ask yourself the following questions and if one or more apply then it is acceptable to inherit an interface from another.

  1. Does interface A logically extend interface B, for example IList adding functionality to ICollection.
  2. Does interface A need to define behaviour already specified by another interface, for example implementing IDisposable if it has resources which need to be tidied up or IEnumerable if it can be iterated over.
  3. Does every implementation of interface A require the behaviour specified by interface B?

In your example, I don't think it answers yes to any of those. You may be better off adding it as another property:

public interface IContextProvider
{
   IDataContext DataContext { get; set; }
   IAreaContext AreaContext { get; set; }
   IEventContextFactory EventContextFactory { get; set; }
}
share|improve this answer
    
How would making it a property be any better than extending the interface, or is it just another way to skin the cat so to speak? –  dreza Sep 5 '12 at 2:38
    
The difference is that if you make IContextProvider extend IEventContextFactory, then the ContextProvider implementation will need to implement that method too. If you add it as a property, you are saying that a ContextProvider has an IEventContextFactory but doesn't actually know the implementation details. –  Trevor Pilley Sep 5 '12 at 7:35
add comment

Yes, it's fine to extend one interface from another.

The question of whether it's the right thing to do in a specific case depends on whether there's a true "is-a" relationship between the two.

What's required for a valid "is-a" relationship?

First, there must be a real difference between the two interfaces, i.e., there must be instances that implement the parent interface but not the child interface. If there are not and never will be instances that don't implement both interfaces, then the two interfaces should instead be merged.

Second, it must be the case that every instance of the child interface must necessarily be an instance of the parent: there's no (reasonable) logic under which you would create an instance of the child interface that wouldn't make sense as an instance of the parent interface.

If both of those are true, then inheritance is the right relationship for the two interfaces.

share|improve this answer
    
I think having classes that use only the base interface and not the derived one is not necessary. For example, the interface IReadOnlyList can be useful, even if all my list classes implement IList (which is derived from IReadOnlyList). –  svick Sep 5 '12 at 9:46
add comment

If the one interface always wants to require/provide the other, then go ahead. I've seen this in a few cases with IDisposible that have made sense. In general though, you should make sure that at least one of the interfaces behaves more like a trait than a responsibility.

For your example, it is not clear. If they are both always together, just make one interface. If one always needs the other, I would be concerned about "X and 1" sort of inheritance that very often leads to multiple responsibilities, and/or other leaky abstraction issues.

share|improve this answer
    
Thanks for that. What do you mean by behave more like a trait than a responsibility? –  dreza Sep 4 '12 at 21:37
    
@dreza I mean responsibility as in SRP in SOLID, and trait like something like Scala traits. Mostly the concept of how the interface models your problem. Does it represent a primary part of the problem or a view into a common piece of otherwise disparate types? –  Telastyn Sep 5 '12 at 0:21
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.