Recently it came to my attention that hierarchical inheritance may be a relic of thinking of classes as "structs with functions" rather than a product contract-driven mentality.

Consider, as a simple specimen the implementation of "Unmodifiable Iterator" from Guava. http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/UnmodifiableIterator.html It's an iterator which throws an "UnsupportedOperationException" on invocation of remove().

Now, I'm sure most people would agree that implementing a contract and then having one of its methods always throw an exception is bad form -- when you implement a contract you're implicitly guaranteeing that all the methods would work. Yet, what are our options here? We could declare an interface which does not contain the remove method but that would render our return type incompatible with all methods which work on iterators. We could blame the Java API designers for forcing the remove() method to be a part of every iterator, rather than moving it to a higher level interface such as "RemovableIterator".

If they did that it would indeed avoid some problems but let's say we need an iterator which can also set values called "SettableIterator" (implements setValue(T) ) and also a resettable iterator. If we require a combination of these functionalities we are forced to declare an interface for every combination. RessetableSettableIterator, RessetableRemovableIterator, RemovableSettableIterator , etc. The combinations grow exponentially to the extra features we add to the interface.

What we are usually trying to express is something like 'this function requires a parameter which is Iterable, Settable and Ressetable' or 'this function returns a value which is Iterable and Resettable'. Yet languages like C#, Java and C++ do not allow us to do this without very awkward use of generics.

Are there recent methods that make this kind of design obsolete?

  • 1
    You're the one asking the question, you should be the one to reformulate it. Your very first sentence makes this 'not constructive,' and as far as I can tell the rest is 'not a real question.' Please review the FAQ for tips on writing questions that are well suited for Programmers.SE. – Caleb Sep 27 '11 at 6:38
  • I'm trying to discuss a rather complex and important topic, Caleb. Hopefully some developers would find this constructive. – Maxaon3000 Sep 27 '11 at 6:47
  • Hi Maxaon3000, Programmers.SE isn't a discussion board: if you're looking for help with a practical, solvable problem, feel free to ask about that instead. – user8 Sep 27 '11 at 7:35

The primary purpose of interfaces is to enable reuse of calling code without having to rewrite it for every possible kind of Iterator (or whatever) object. In your example, the Liskov substitution violation eliminates a good chunk of that code from being reused properly, but this particular interface is so extremely widespread that there is a significant amount of reusable code even with that elimination. The alternative here is to redesign the hierarchy to take unmodifiable iterators into account, and in the process have to rewrite any existing code to use the new classes, some of which you may not have source for. In other words, there are exceptions to every rule.

Also note that you do not have to declare a new interface for every possible combination, you can just require multiple interfaces. You would not need a RemovableResettableIterator, just a RemovableIterator and ResettableIterator and require one or the other or both as appropriate.

  • You may be able to require both interfaces through an awkward use of generics -- <T extends RemovableIterator & ResettableIterator> func (T arg_) but there is no way at all to return a value implementing both in a type safe manner. – Maxaon3000 Sep 27 '11 at 7:28

The answer to the title question is objectively no. There are a number of paradigms in software development, and inheritance-driven OOP is among the most successful because it works well for a great many problems. That doesn't mean that there's no room for new paradigms, or that they won't also find some success.

Whatever the merits of any new paradigms or the drawbacks of inheritance, inertia alone will guarantee that inheritance will be with us for some time to come. And the fact that as of this writing you haven't clearly articulated the alternative that's supposed to be the subject of your question leads me to believe that its successor is not immediately apparent.

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