Do/can abstract classes replace interfaces?

12,046

Solution 1

Not always:

  • a class can extend only one class
  • a class can implement more than one interface

Sun docs make a more detailed comparison:

Abstract Classes versus Interfaces

Unlike interfaces, abstract classes can contain fields that are not static and final, and they can contain implemented methods. Such abstract classes are similar to interfaces, except that they provide a partial implementation, leaving it to subclasses to complete the implementation. If an abstract class contains only abstract method declarations, it should be declared as an interface instead.

Multiple interfaces can be implemented by classes anywhere in the class hierarchy, whether or not they are related to one another in any way. Think of Comparable or Cloneable, for example.

By comparison, abstract classes are most commonly subclassed to share pieces of implementation. A single abstract class is subclassed by similar classes that have a lot in common (the implemented parts of the abstract class), but also have some differences (the abstract methods).

Solution 2

In some cases you can use an abstract class instead of interface. However, it is hardly ever a good idea to do so. In general you should use the rule:

  1. Interfaces specify behaviour.
  2. Abstract classes specify implementation.

The other "problem" with using abstract classes is that you can then no longer implement mixins, that is you can implement multiple interfaces, however you can only extend one abstract class.

Solution 3

One point missing from the answers here is the idea of who will be implementing the interface.

If your component wants to return instances of abstract types to its callers, where the concrete types are defined internally and hidden from callers, use an interface. Conversely, if your component consumes or accepts instances of abstract types that its callers must implement, abstract classes are usually a better choice.

Anticipating evolution and maintaining binary compatibility tips the scales here. With an abstract class, you can add methods and, if you provide a base implementation, existing implementations of the abstract class will continue to work fine. With an interface, adding a method breaks binary compatibility, for no existing implementation could possibly continue to compile properly without changing to define the new method.

The Apache Cactus project has a good discussion on how to resolve these obligations.

Solution 4

To answer your question, yes you could use an abstract class (providing no implementation) instead of an interface but I'd consider this bad practice:

  • You've used up your "one-shot" at inheritance (without gaining any benefit).
  • You cannot inherit from multiple abstract classes but you can implement multiple interfaces.

I would advocate the use of abstract classes more in situations where you wish to provide a partial implementation of a class, possibly delegating some behavior to concrete subclass implementations.

Solution 5

Abstract classes and interfaces are complementary.

For instance when creating an API you will want to present interfaces to the client, so that you may always completely change the implementation whereas he does not have to change its code and the user does not rely on implementation when building using your API but just on methods contracts.

Then you will have abstract classes partly implementing these interfaces, in order to

  • share some common code, which might be used in all (or almost all) implementations for interface, which is obvious
  • provide default behaviour which could be overridden in 'real' implementations, for instance a toString() method using interfaces methods to create a textual representation of the implementation
  • preserve implementations compatibility after interface changes, for instance when you add a new method in your interface, you also add a default implementation in the abstract class so that implementations (for instance those made by the user) extending the abstract class still work without changes
Share:
12,046
Registered User
Author by

Registered User

Updated on June 16, 2022

Comments

  • Registered User
    Registered User almost 2 years

    In Java, you can create an abstract class that contains only abstract methods. On the other hand, you can create an interface that declares the same methods. That being the case, can you use abstract classes instead of interfaces?

  • Hakanai
    Hakanai over 11 years
    But... at least you can add a method to an abstract class without breaking every subclass anyone ever created.
  • Paul Wagland
    Paul Wagland over 11 years
    @Trejkaz In Java v8 that will (probably) also be the case: javabeat.net/2012/05/virtual-extension-methods-in-java-8
  • Hakanai
    Hakanai over 11 years
    Interesting, finally traits will enter Java itself, reducing the temptation to switch to Scala. :) (By the way, I dodge this problem in my interface-based APIs by putting all the extension methods onto a separate utility class... but it looks uglier when you call it.)