[java] When to use: Java 8+ interface default method, vs. abstract method

Java 8 allows for default implementation of methods in interfaces called Default Methods.

I am confused between when would I use that sort of interface default method, instead of an abstract class (with abstract method(s)).

So when should interface with default methods be used and when should an abstract class (with abstract method(s)) be used? Are the abstract classes still useful in that scenario?

This question is related to java interface java-8 abstract-class default-method

The answer is


There are a few technical differences. Abstract classes can still do more in comparison to Java 8 interfaces:

  1. Abstract class can have a constructor.
  2. Abstract classes are more structured and can hold a state.

Conceptually, main purpose of defender methods is a backward compatibility after introduction of new features (as lambda-functions) in Java 8.


In Java 8, an interface looks like an abstract class although their might be some differences such as :

1) Abstract classes are classes, so they are not restricted to other restrictions of the interface in Java e.g. abstract class can have the state, but you cannot have the state on the interface in Java.

2) Another semantic difference between interface with default methods and abstract class is that you can define constructors inside an abstract class, but you cannot define constructor inside interface in Java


This is being described in this article. Think about forEach of Collections.

List<?> list = …
list.forEach(…);

The forEach isn’t declared by java.util.List nor the java.util.Collection interface yet. One obvious solution would be to just add the new method to the existing interface and provide the implementation where required in the JDK. However, once published, it is impossible to add methods to an interface without breaking the existing implementation.

The benefit that default methods bring is that now it’s possible to add a new default method to the interface and it doesn’t break the implementations.


These two are quite different:

Default methods are to add external functionality to existing classes without changing their state.

And abstract classes are a normal type of inheritance, they are normal classes which are intended to be extended.


Although its an old question let me give my input on it as well.

  1. abstract class: Inside abstract class we can declare instance variables, which are required to the child class

    Interface: Inside interface every variables is always public static and final we cannot declare instance variables

  2. abstract class: Abstract class can talk about state of object

    Interface: Interface can never talk about state of object

  3. abstract class: Inside Abstract class we can declare constructors

    Interface: Inside interface we cannot declare constructors as purpose of
    constructors is to initialize instance variables. So what is the need of constructor there if we cannot have instance variables in interfaces.

  4. abstract class: Inside abstract class we can declare instance and static blocks

    Interface: Interfaces cannot have instance and static blocks.

  5. abstract class: Abstract class cannot refer lambda expression

    Interfaces: Interfaces with single abstract method can refer lambda expression

  6. abstract class: Inside abstract class we can override OBJECT CLASS methods

    Interfaces: We cannot override OBJECT CLASS methods inside interfaces.

I will end on the note that:

Default method concepts/static method concepts in interface came just to save implementation classes but not to provide meaningful useful implementation. Default methods/static methods are kind of dummy implementation, "if you want you can use them or you can override them (in case of default methods) in implementation class" Thus saving us from implementing new methods in implementation classes whenever new methods in interfaces are added. Therefore interfaces can never be equal to abstract classes.


when should interface with default methods be used and when should an abstract class be used?

Backward compatibility: Imagine that your interface is implemented by hundreds of classes, modifying that interface will force all the users to implement the newly added method, even though it could be not essential for many other classes that implements your interface, Plus it allows your interface to be a functional interface

Facts & Restrictions:

1-May only be declared within an interface and not within a class or abstract class.

2-Must provide a body

3-It is not assumed to be abstract as other normal methods used in an interface.


Please think first of open/closed principle. The default methods in interfaces DO VIOLATE it. This is a bad feature in Java. It encourages bad design, bad architecture, low software quality. I would suggest to avoid using default methods completely.

Ask yourself a few questions: Why can't you put your methods to the abstract class? Would you need then more than one abstract class? Then think about what is your class responsible for. Are you sure all methods you are going to put to the single class really fulfill the same purpose? May be you will distinguish several purposes and will then split your class into several classes, for each purpose its own class.


Default methods in Java Interface are to be used more for providing dummy implementation of a function thus saving any implementing class of that interface from the pain of declaring all the abstract methods even if they want to deal with only one. Default methods in interface are thus in a way more a replacement for the concept of adapter classes.

The methods in abstract class are however supposed to give a meaningful implementation which any child class should override only if needed to override a common functionality.


Remi Forax rule is You don't design with Abstract classes. You design your app with interfaces. Watever is the version of Java, whatever is the language. It is backed by the Interface segregation principle in SOLID principles.

You can later use Abstract classes to factorize code. Now with Java 8 you can do it directly in the interface. This is a facility, not more.


Whenever we have a choice between abstract class and interface we should always (almost) prefer default (also known as defender or virtual extensions) methods.

  1. Default methods have put an end to classic pattern of interface and a companion class that implements most or all of the methods in that interface. An example is Collection and AbstractCollection. Now we should implement the methods in the interface itself to provide default functionality. The classes which implement the interface has choice to override the methods or inherit the default implementation.

  2. Another important use of default methods is interface evolution. Suppose I had a class Ball as:

    public class Ball implements Collection { ... }

Now in Java 8 a new feature streams in introduced. We can get a stream by using stream method added to the interface. If stream were not a default method all the implementations for Collection interface would have broken as they would not be implementing this new method. Adding a non-default method to an interface is not source-compatible.

But suppose we do not recompile the class and use an old jar file which contains this class Ball. The class will load fine without this missing method, instances can be created and it seems everything is working fine. BUT if program invokes stream method on instance of Ball we will get AbstractMethodError. So making method default solved both the problems.

Java 9 has got even private methods in interface which can be used to encapsulate the common code logic that was used in the interface methods that provided a default implementation.


As described in this article,

Abstract classes versus interfaces in Java 8

After introducing Default Method, it seems that interfaces and abstract classes are same. However, they are still different concept in Java 8.

Abstract class can define constructor. They are more structured and can have a state associated with them. While in contrast, default method can be implemented only in the terms of invoking other interface methods, with no reference to a particular implementation's state. Hence, both use for different purposes and choosing between two really depends on the scenario context.


Regarding your query of

So when should interface with default methods be used and when should an abstract class be used? Are the abstract classes still useful in that scenario?

java documentation provides perfect answer.

Abstract Classes Compared to Interfaces:

Abstract classes are similar to interfaces. You cannot instantiate them, and they may contain a mix of methods declared with or without an implementation.

However, with abstract classes, you can declare fields that are not static and final, and define public, protected, and private concrete methods.

With interfaces, all fields are automatically public, static, and final, and all methods that you declare or define (as default methods) are public. In addition, you can extend only one class, whether or not it is abstract, whereas you can implement any number of interfaces.

Use cases for each of them have been explained in below SE post:

What is the difference between an interface and abstract class?

Are the abstract classes still useful in that scenario?

Yes. They are still useful. They can contain non-static, non-final methods and attributes (protected, private in addition to public), which is not possible even with Java-8 interfaces.


As mentioned in other answers, the ability to add implementation to an interface was added in order to provide backward compatibility in the Collections framework. I would argue that providing backward compatibility is potentially the only good reason for adding implementation to an interface.

Otherwise, if you add implementation to an interface, you are breaking the fundamental law for why interfaces were added in the first place. Java is a single inheritance language, unlike C++ which allows for multiple inheritance. Interfaces provide the typing benefits that come with a language that supports multiple inheritance without introducing the problems that come with multiple inheritance.

More specifically, Java only allows single inheritance of an implementation, but it does allow multiple inheritance of interfaces. For example, the following is valid Java code:

class MyObject extends String implements Runnable, Comparable { ... }

MyObject inherits only one implementation, but it inherits three contracts.

Java passed on multiple inheritance of implementation because multiple inheritance of implementation comes with a host of thorny problems, which are outside the scope of this answer. Interfaces were added to allow multiple inheritance of contracts (aka interfaces) without the problems of multiple inheritance of implementation.

To support my point, here is a quote from Ken Arnold and James Gosling from the book The Java Programming Language, 4th edition:

Single inheritance precludes some useful and correct designs. The problems of multiple inheritance arise from multiple inheritance of implementation, but in many cases multiple inheritance is used to inherit a number of abstract contracts and perhaps one concrete implementation. Providing a means to inherit an abstract contract without inheriting an implementation allows the typing benefits of multiple inheritance without the problems of multiple implementation inheritance. The inheritance of an abstract contract is termed interface inheritance. The Java programming language supports interface inheritance by allowing you to declare an interface type


Default methods in Java interface enables interface evolution.

Given an existing interface, if you wish to add a method to it without breaking the binary compatibility with older versions of the interface, you have two options at hands: add a default or a static method. Indeed, any abstract method added to the interface would have to be impleted by the classes or interfaces implementing this interface.

A static method is unique to a class. A default method is unique to an instance of the class.

If you add a default method to an existing interface, classes and interfaces which implement this interface do not need to implement it. They can

  • implement the default method, and it overrides the implementation in implemented interface.
  • re-declare the method (without implementation) which makes it abstract.
  • do nothing (then the default method from implemented interface is simply inherited).

More on the topic here.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to interface

Cast object to interface in TypeScript When to use Interface and Model in TypeScript / Angular Is there a way to create interfaces in ES6 / Node 4? Can a normal Class implement multiple interfaces? When to use: Java 8+ interface default method, vs. abstract method How should I have explained the difference between an Interface and an Abstract class? When do I have to use interfaces instead of abstract classes? How to extend a class in python? Interface type check with Typescript Abstract Class vs Interface in C++

Examples related to java-8

Default interface methods are only supported starting with Android N Class has been compiled by a more recent version of the Java Environment Why is ZoneOffset.UTC != ZoneId.of("UTC")? Modify property value of the objects in list using Java 8 streams How to use if-else logic in Java 8 stream forEach Android Studio Error: Error:CreateProcess error=216, This version of %1 is not compatible with the version of Windows you're running Error:could not create the Java Virtual Machine Error:A fatal exception has occured.Program will exit What are functional interfaces used for in Java 8? java.time.format.DateTimeParseException: Text could not be parsed at index 21 Java 8 lambda get and remove element from list

Examples related to abstract-class

invalid new-expression of abstract class type Class is not abstract and does not override abstract method When to use: Java 8+ interface default method, vs. abstract method Spring can you autowire inside an abstract class? Abstract Class:-Real Time Example How should I have explained the difference between an Interface and an Abstract class? When do I have to use interfaces instead of abstract classes? Is it possible to make abstract classes in Python? Abstract Class vs Interface in C++ How do you handle a "cannot instantiate abstract class" error in C++?

Examples related to default-method

When to use: Java 8+ interface default method, vs. abstract method