In Java, what is the difference between an abstract class and an interface?

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.

Q: Huh??!!!

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.

About these ads

14 thoughts on “In Java, what is the difference between an abstract class and an interface?

  1. Except the problem still comes up, because you can have two interfaces with the same method name. In this case, Java offers no real usable solution: you’re forced to use one implementation for both interfaces, even if that is inappropriate.

    C# solves this problem through explicit interface implementation, yet retains the class and interface dichotomy of Java. This is because classes have constructors and therefore require the language to resolve the initialization issues, including the dreaded diamond. To the best of my knowledge, the initialization issues are the real reason interfaces exist in both languages, not the possibility of duplicate method names.

  2. Your ending statement is true if and only if you consider “single inheritance” a “limited form of multiple inheritance”.

    • The difference between ‘invokevirtual’ and ‘invokeinterface’ mean that his ending statement is true period, regardless of how you arrange the relationship between single and multiple inheritance. If Java only supported single inheritance, I wouldn’t need two seperate opcodes, with two seperate behaviors, to achieve dynamic binding.

  3. A BIG difference is: ABC are compiled into code, interfaces aren’t.
    In my opinion, that’s a big point FOR interfaces!

    • Huh? Interfaces are most certainly compiled into code: look at the definition of the invokeinterface opcode!

  4. My comment is regarding your definition of an abstract class in Java. I first want to say though I find your postings to be of, generally, very high quality and found reading them helpful.

    Your definition or an abstract class as being ‘partially’ or ‘fully’ abstract, in my opinion, neglects the definitions of abstract and interface classes. Hopefully this will clear things up:

    The purpose of an abstract class is when the creator wants aspects of their class’s implementation to be defined in the subclass, while others are defined in the parent abstract class. In other words, some methods are written in the abstract class while others are written in the implementing concrete class. This constrains the behavoiur of all subclasses to the parent’s control to a greater degree than interfaces, which only specify method headers.

    When you refer to abstract classes as being fully abstract, it is the same as an interface. This will only occur in improper implementation of Java’s OO, since a ‘fully’ abstract class is by definition an interface. This is analogous to writing non-OO programs in Java: although it is a fully OO language and forces you to use its OO constructs, one may chose to write non-OO code or improper OO code (creating interfaces as abstract classes).

    • You need to read up on the Liskov Substitution principal. Abstract classes do not constrain behavior any more or any less than interfaces. Child classes must always strictly obey the interface outlined by their parent class(es) or interfaces, even if their parent is a concrete class. This includes both the written rules (e.g., type information) and the unwritten rules (e.g., performance characteristics, invariants).

      Abstract classes, as best as I can tell, were added to Java because implementation inheritance is simply too convenient to ignore, and people would have gotten sick of writing AWT stub event handlers awfully quickly. There are legitimate cases where providing partial functionality makes sense, but they’re pretty rare in the grand scheme of things. There’s usually a better way to accomplish whatever is desired.

    • Thanks Amit, that was an interesting post. I found this thought in your post (which I have rephrased) especially interesting.

      The general rule is — if you are creating something that provides common functionality to unrelated classes, use interface. For example, suppose we have separate classes for Bird and Airplane. Both classes need a fly() method, but it would be ridiculous for Airplane to inherit from Bird, or from Bird to inherit from Airplane, just to get the fly() method . Rather the fly() method should be defined as an interface (Flyable ?) and both Airplane and Bird should implement that interface.

      That stimulated this thought on my part…

      You can think of object-oriented programming (or if you prefer, domain-driven design) as a means of creating computerized representations of real-world objects. The computerized representations include representations of (a) the attributes of real-world objects, and (b) the behaviors of real-world objects.

      You can think of a class as a tool for creating a computerized representation of a certain kind of thing, such airplanes and birds.

      You can think of an interface as a tool for creating (or more properly, for forcing the creation of) a computerized representation of a certain kind of behavior, such as flying (which airplanes and some kinds of birds can do, but ostriches and penguins cannot do), running (which airplanes and penguins cannot do, but ostriches can do), and swimming (which airplanes and ostriches cannot do, but penguins can).

      As I say, just a thought…

  5. An interface is also a concept programmers can refer to, to not couple the implementation.

    For instance, say you’re programming (plane) avionics, basically a speedometer for instance.
    The Cessna API defines the SpeedProvider interface, with the method speedChanged(float newSpeed).

    Now, what’s great is that Cessna programmers didn’t have to know how this speed information will be get. It only want to be coupled to a method doing it, i.e. a class implementing the SpeedProvider and the speedChanged() method.
    Which means the avionics can be connected to real plane measurement or to a flight simulator.
    (This example is real. Any Cessna “glass cockpit” can really work with X-Plane. You could probably write your own simulator and use it.)

    What I mean with this message is that interfaces can also be seen as a way to extend existing software, to write plugins.

    Multiple inheritance can be replaced with other techniques, most of the time by using interfaces…

  6. This is a very good article. Thank you for taking the time to have it written for newbies like me in java

  7. Just adding my 2 cents:

    In java, it’s possible to have an Abstract class which DOES NOT contain any Abstract methods.

  8. In Java:
    1. an Abstract Class can have from 0 to n Abstract Methods, so the statement an Abstract Class is a class that contains abstract methods only is totally wrong
    2. an Abstract Class can contain private, protected and public methods/fields, an Interface can contain public method firms only and public constants, therefore they are pretty different as code statements
    3. an Abstract Class defines a kind of object that must be inherited to have its properties, an Interface defines an aspect or a behaviour of an object, therefore once again they are pretty different things

    be careful when writing such kind of articles, since most of the people reads you and very often they don’t care to check if what you’re saying is correct or less.

Comments are closed.