Look for examples / cases where mutual interface inheritance is required (rather than implementation)

Both C # and Java support interfaces inheriting from multiple parents:

public interface IMyInterface : IInterface1, IInterface2 

 public interface MyInterface extends Interface1, Interface2 

I looked in the .NET Framework and JavaAPI documentation for examples that use multiple interface inheritance.

In JavaAPI, I find examples of subinterfaces that extend the superinterface and one or more marker interfaces (that is, they do not have specific methods). Thus, token interfaces actually do nothing in the implementation. I see this in favor of this, especially before introducing annotations.

In .NET, I find interfaces that inherit from multiple parents that are already connected. For example, IList inherits from ICollection and IEnumerable , but ICollection already a descendant of IEnumerable . Thus, enforcing IEnumerable in an implementation already executes with a single inheritance.

In any case, it seems that the inheritance of several interfaces is either redundant or can be replaced by a better alternative.

Are there any examples that would be difficult or impossible to complete without multiple interface inheritance?

+4
source share
4 answers

If I understand how you described the .NET interface inheritance chain, then you are mistaken. This is not an easy mistake, as in the documentation it looks like this. IList<T> only explicitly inherits from ICollection<T> ; it does not inherit from ICollection<T> , IEnumerable<T> and IEnumerable . Here's the actual definition from the original source:

 public interface IList<T> : ICollection<T> 

The same applies to ICollection<T> , it inherits only from IEnumerable<T> . At compile time, the inheritance tree is smoothed and deduplicated, in a sense, for interfaces. Thus, an interface that inherits ICollection does not just inherit this interface, which in turn inherits IEnumerable . Rather, the interface inherits ICollection and IEnumerable itself.

Illustrative example:

 IMine : ICollection<T> != IMine : (ICollection<T>:(IEnumerable<T>:IEnumerable)) 

Instead, it looks like this:

 IMine: ICollection<T>, IEnumerable<T>, IEnumerable 

This explains why you made the conclusion that you have.


For an example of a real set of multiple interface inheritance, see the IQueryable and IOrderedQueryable . The actual source declaration of these interfaces is as follows:

 public interface IQueryable<out T> : IEnumerable<T>, IQueryable {} public interface IOrderedQueryable<out T> : IQueryable<T>, IOrderedQueryable {} 

IQueryable should have a contract that indicates that you can iterate over each element, as well as the ability to be different from plain IEnumerable in that it is one, not all IEnumerable types can be used in IQueryProvider and the static Queryable class.


Another interesting is the System.Collections.Concurrent namespace.

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

This is interesting because it inherits from ICollection (non-generic) and IEnumerable<T> , which both inherit from IEnumerable . Of course, this is not a problem, but this is another good example. If IProducerConsumerCollection<T> were to inherit from ICollection<T> instead of its non-shared instance, I am sure that it does not explicitly inherit from IEnumerable<T> . It has the size, (old) enumerator and the behavior of the synchronization methods defined in ICollection , and then also the general enumeration behavior defined in IEnumerable<T>

There are two examples. I found more, but I think that they are probably enough.

+1
source

You should take a look at the Interface Segregation Principle (ISP) of the MODERN principles . Basically, you should create small interfaces that connect together, and not try to find a way to combine them. Why are methods that are not useful for some classes forced? This is usually the cause of multiple inheritance.

As for whether the design would be impossible, I would say no, since you could just create a giant interface. However, the ISP points to the negativity of this approach, which would make maintenance a potential difficulty, but without the initial design, I would say that you do not need multiple inheritance to complete the implementation. It may look dirty, that's all

+1
source

If you want all objects implementing your interface to be IDisposable and IComparable .

For example, if you have a set of resources that you can order or filter (using IEquatable) based on some of your properties. This means that all objects must implement both interfaces, and you can use a common interface to provide this.

 IResource<T>: IDisposable, IComparable<T>, IEquatable<T> 
+1
source

In Java:

Comparable often stands out from the main type.

AbstractList subtypes of both AbstractCollection and List .

StringBuilder is CharSequence (read interface) and Appendable (write interface). I'm not too keen to combine reading and writing together - immutable values โ€‹โ€‹and tell-don't-ask interfaces.

Obviously, there are (mostly evil) marker interfaces: Serializable , Cloneable and RandomAccess .

In particular, the GUI code has a completely unnecessary implementation of callback interfaces into one error class, which usually extends the class to which it had no reason.

0
source

Source: https://habr.com/ru/post/1402492/


All Articles