Some object-oriented programming languages like C++ permit a class to have multiple superclasses. This form of inheritance, which is called multiple inheritance, is very controversial. While clever uses of multiple inheritance undoubtedly exist, the semantics of code and field inheritance with multiple superclasses is problematic because of name clashes between members and, worse, the possibility of inheriting the same class in more than one way. Recent programming language research suggests that there are better approaches to inheritance that combine the flexibility of multiple inheritance with the simplicity of single inheritance, but they are currently the subject ongoing research and experimentation.
Java supports multiple interface inheritance, which the most attractive proven alternative to multiple inheritance. In multiple interface inheritance, a class can extend multiple lightweight abstract classes, but only one class that includes method code and fields. Since no method code or fields appears in the lightweight abstract classes, there is no problem with name clashes (since all interface methods are publicly visible) or inheriting the same interface in multiple ways. We will illustrate the utility of Java interfaces in the next section. At this point, all we can say is that the abstract classes DeptDirectory and IntList could be declared as interfaces instead if we were willing to make all of their methods public and delete the main method in IntList included for testing purposes.
Since the abstract class DeptDirectory above does not contain any members, it could be trivially rewritten as follows:
interface DeptDirectory {}
This change forces a small change in the definition of any immediate subclass of DeptDirectory: the word implements must be used in the header instead of extends:
In short, a class implements an interface but extends a class.class Empty implements DeptDirectory ... class Cons implements DeptDirectory ...
We generally recommend using abstract classes as the root classes in composite hierarchies because they frequently need to introduce methods that should be hidden (not public) and methods that are not abstract. On the other hand, some programs involve multiple composite class hierarchies that share concrete subclasses. In this case, you must define the root classes as interfaces or define two copies of the ``shared'' classes.