How does the JLS specify the terms "abstract method", "concrete method" and "default method"?

According to the JLS 8.4.3.1:

"An abstract method declaration introduces the method as a member, providing its signature (§8.4.2), result (§8.4.5), and throws clause if any (§8.4.6), but does not provide an implementation (§8.4.7). A method that is not abstract may be referred to as a concrete method."

According to JLS 9.4:

"A default method is an instance method declared in an interface with the default modifier. Its body is always represented by a block, which provides a default implementation for any class that implements the interface without overriding the method. Default methods are distinct from concrete methods (§8.4.3.1), which are declared in classes, and from private interface methods, which are neither inherited nor overridden."

So according to this taxonomy there are really 4 types of methods:


Note that JLS 8.4.3.1 makes no mention of final or static in the distinction between abstract and concrete methods.

These modifiers cannot be used with the abstract keyword. This implies that methods that are static or final must be concrete methods. This reinforces the 8.4.3.1 definition of a concrete method.


Abstract Method

An abstract method is defined in the Java Language Specification (JLS) Section 8.4.3.1 as:

An abstract method declaration introduces the method as a member, providing its signature (§8.4.2), result (§8.4.5), and throws clause if any (§8.4.6), but does not provide an implementation (§8.4.7).

In practice, an abstract method is any method whose signature is defined, but no implementation is provided. For example, methods in an interface and methods qualified with the abstract keyword in an abstract class are both abstract methods:

public interface Foo {
    void someAbstractMethod();
}

public abstract class Bar {

    public abstract someAbstractMethod();

    // ...

}

Concrete Method

According to JLS Section 8.4.3.1, a concrete method is defined as:

A method that is not abstract may be referred to as a concrete method.

In practice, this means any method for which an implementation is provided:

public FooImpl implements Foo {

    @Override
    public void someAbstractMethod() {
        // ... some implementation ...
    }

}

Default Method

Default method are defined in JLS Section 9.4:

A default method is an instance method declared in an interface with the default modifier. Its body is always represented by a block, which provides a default implementation for any class that implements the interface without overriding the method. Default methods are distinct from concrete methods (§8.4.3.1), which are declared in classes, and from private interface methods, which are neither inherited nor overridden.

The same section also adds:

An interface can declare static methods, which are invoked without reference to a particular object. static interface methods are distinct from default methods, which are instance methods.

Default methods were created with a specific purpose. In JDK 8, functional interfaces were added to Java. This required that interfaces be updated to include functional methods, but doing so would require that all existing implementations of these interfaces (including in 3rd party libraries and frameworks) would be required to provide an implementation. Instead, the Java team introduced default methods, which are interface methods that provide a default implementation that is used when no implementation is provided by overriding classes.

This should not be used as an alternative to abstract classes. It is intended for a specific purpose and should be used for that purpose.

In practice, a default method is created using the default keyword:

public interface Foo {

    public default void someMethod() {
        // ... some default implementation ...
    }
}

This default implementation can be overridden in concrete subclasses:

public class FooImpl implements Foo {

    @Override
    public void someMethod() {
        // ... some overriding implementation ...
    }
}

Additionally, according to JLS Section 9.4.1.1, the default implementation of a method (the body of a default method) can be accessed in concrete subclasses using the super keyword, qualified by the interface name:

An overridden default method can be accessed by using a method invocation expression (§15.12) that contains the keyword super qualified by a superinterface name.

For example:

public class FooImpl implements Foo {

    @Override
    public void someMethod() {
        Foo.super.someMethod();
    }
}

The interface name is used as a qualifier because a class can implement multiple interfaces (or an interface can extend multiple interfaces). For more information, see Explicitly calling a default method in Java.