There are many reasons why Java has it's own construct for multiple inheritance, i.e. with interface
and abstract
classes. Here are three that I can think of:
It reduces boilerplate code (i.e. pure virtual functions)
In languages that don't have the interface
construct, you have to do a lot of boilerplate coding. Consider in C++ you need to create a class that have pure virtual functions:
class MyInterface
{
public:
virtual void show() = 0;
virtual int number() = 0;
};
class ConcreteImpl : public MyInterface
{
public:
void show()
{
cout << "Concrete Impl here";
}
int number()
{
return 1337;
}
};
The equivalent in Java would be less verbose, mostly because methods are virtual (overridable) functions. And it is more apparent that one of the artifacts is the interface.
interface MyInterface {
void show();
int number();
}
class ConcreteImpl implements MyInterface {
public void show() {
System.out.println("Concrete Impl here");
}
public int number() { return 1337; }
}
Java does allow a class with mixed pure virtual and implementation, with the abstract
keyword.
It constrains the "diamond inheritance" problem
One of the problems associated with multiple inheritance is the hairy diamond inheritance problem. Consider if you have a language that allows this chain of classes in a language such as C++:
Think of a SuperBaseClass
that has two implemented BaseClass
, both implementing the SuperBaseClass
's method as virtual functions. In turn both BaseClass
's are implemented by the MyImplementation
class. Consider what will happens if you call super()
in MyImplementation.draw()
? It is not always apparent what will happen, even in C++, developers who have designed this will find themselves in a weird debugging session.
There is nothing particular wrong with diamond inheritance, so to avoid the problems of calling the super-method, you have to design them either by using pure virtual functions or design them in a smarter fashion. In Java, since all methods are virtual by default, you are constrained by the fact that you can only do multiple inheritance with interface
s since they don't contain any implementation (with the implements
keyword). Other classes, even abstract
ones, can only be single inherited (with the extends
keyword).
Seasoned devs were already using interfaces as a concept (circa 1995)
If you got into Design Patterns by GoF, you will notice that they rely heavily on interfaces to design extensible systems. In fact one of the principles of Design Patterns is:
"Program to an 'interface', not an 'implementation'." (Gang of Four 1995:18)
Interface in the GoF sense means that you should program towards a superclass rather than the implementation. One example would be that you should prefer typing your variable to Collection<T>
, Iterable<T>
, or List<T>
instead of ArrayList<T>
in Java if the only methods you use on the object is to iterate it. A pattern example from GoF would be the strategy pattern where the context doesn't need to know the exact strategy it is given to execute, but will execute the set one, regardless of what it was.