views:

140

answers:

5

I don't necessarily see a grandiose benefit of interfaces inheriting interfaces.

Consider the following three interfaces, the third inheriting the other two

interface IOne {
}

interface ITwo {
}

// interface inheritance
interface IAll : IOne, ITwo {
}

Is it best to

class C : IOne, ITwo { ... }

or

class C : IAll { ... }

If the latter can be beneficial then why not just create IAll to have all the methods of both IOne and ITwo without inheriting from them? After all it's an interface.

Is interface inheritance practical, not just useful?

A: 

I would go with first approach, it is much clearer to me. Second one seems contrived, IMO.

fastcodejava
A: 

There might be methods which want an IAll argument -- so if you meet the requirements to implement the whole of IAll, it's convenient to do so, rather than just implement each of the interfaces it extends!

Normally, of course, interfaces aren't empty, so there's a specific (maybe small) cost in implementing one and/or the other (different, multiple methods will need to get implemented). If, say, IFirst has a method foo, and ISecond has a method bar, it makes perfect sense to extend both into an IBoth even if that doesn't add further needed methods -- it allows a method to clearly express that it needs an argument that has both methods, foo and bar.

If every interface in the world was empty, their very use (much less extending them with further empty interface) would be much more dubious of course!-)

Alex Martelli
A: 

Yes, interface inheritance is practical. The idea behind interfaces is that a single interface defines a loose "contract" describing a specific set of functionality. This allows a very clean separation of functionality.

Typically, a class that needs to implement multiple interfaces does so by listing each of the interfaces separately, like:

class C : IOne, ITwo { ... }

If you need the ability to aggregate the functionality from multiple interfaces then you would want to create a single interface that inherits from the others (like your IAll interface). Although you can do this, you generally don't need (or want) to do this.

Scott Dorman
+1  A: 

Do what is semantically correct. Don't do something just to save typing in an extra interface.

If 'IAll' is a concept that has meaning in your program, fine, use it. If it's just a way of not typing 'IFirst, ISecond', don't do it.

kyoryu
+4  A: 

A good way to think about interface "inheritance" is to forget entirely that it is called "inheritance". After all, clearly the "base" interface contributes no functionality to the "derived" interface; all it contributes is the promise that there will be certain members.

A class derivation relationship usually implies an "is-a-kind-of" relationship. A NullReferenceException is-a-kind-of Exception. An interface derivation relationship doesn't imply that at all -- it makes very little sense to say that IEnumerable<T> is a kind of IDisposable.

Rather, interface inheritance means "a type which implements IEnumerable<T> is required to also implement IDisposable. That is, interface inheritance does not mean "this is a kind of that", but rather "every implementation of this is required to also implement that".

Does that make it more compelling?

Eric Lippert
That's a very useful wording that I will try to remember :)
Nij
But how about `interface IList<T> : ICollection<T>, IEnumerable<T>, ...;` ? Every IList<T> IS-A ICollection<T>, right? The substitution principle seems to hold.
Henk Holterman
@Henk: But there is no "is a" relationship with ICollection in the first place. ICollection is an interface; it represents a "can do" relationship, not an "is a kind of" relationship. Interface inheritance means "anything that can do the functions of a list must also provide the functions of a collection and a sequence".
Eric Lippert
@Eric: not to drag it out too long, But if X can do anything that Y can do, then X "is a kind of" Y in my opinion. Especially when "can do" is all there is to X and Y, as is the case with interfaces. At the class/interface boundary I've always regarded this as 2 non-conflicting points of view, _FileStream implements IDisposable_ and _List<> inherits from IList<>_ are both useful, productive concepts.
Henk Holterman