This post is about Java, and has nothing to do with Python. I’ve posted it here so that it can be available to other folks who might find it useful. (And because I don’t have a Java blog!)
In Java, what is the difference between an abstract class and an interface?
This is a question that comes up periodically. When I Googled for answers to it, I didn’t very much like any of the answers that I found, so I wrote my own. For those who might be interested, here it is.
Q: What is the difference between an abstract class and an interface?
A: Good question.
To help explain, first let me introduce some terminology that I hope will help clarify the situation.
- I will say that a fully abstract class is an abstract class in which all methods are abstract.
- In contrast, a partially abstract class is an abstract class in which some of the methods are abstract, and some are concrete (i.e. have implementations).
Q: OK. So what is the difference between a fully abstract class and an interface?
A: Basically, none. They are the same.
Q: Then why does Java have the concept of an interface, as well as the concept of an abstract class?
A: Because Java doesn’t support multiple inheritance. Or rather I should say, it supports a limited form of multiple inheritance.
A: Java has a rule that a class can extend only one abstract class, but can implement multiple interfaces (fully abstract classes).
There’s a reason why Java has such a rule.
Remember that a class can be an abstract class without being a fully abstract class. It can be a partially abstract class.
Now imagine that that we have two partially abstract classes A and B. Both have some abstract methods, and both contain a non-abstract method called foo().
And imagine that Java allows a class to extend more than one abstract class, so we can write a class C that extends both A and B. And imagine that C doesn’t implement foo().
So now there is a problem. Suppose we create an instance of C and invoke its foo() method. Which foo() should Java invoke? A.foo() or B.foo()?
Some languages allow multiple inheritance, and have a way to answer that question. Python for example has a “method resolution order” algorithm that determines the order in which superclasses are searched, looking for an implementation of foo().
But the designers of Java made a different choice. They choose to make it a rule that a class can inherit from as many fully abstract classes it wants, but can inherit from only one partially abstract class. That way, the question of which foo() to use will never come up.
This is a form of limited multiple inheritance. Basically, the rule says that you can inherit from (extend) as many classes as you want, but if you do, only one of those classes can contain concrete (implemented) methods.
So now we do a little terminology substitution:
abstract class = a class that contains at least one abstract method, and can also contain concrete (implemented) methods
interface = a class that is fully abstract — it has abstract methods, but no concrete methods
With those substitutions, you get the familiar Java rule:
A class can extend at most one abstract class, but may implement many interfaces.
That is, Java supports a limited form of multiple inheritance.