Java Programming Tutorials

Java programming tutorials with many code examples!

Java 8 interfaces default and static methods

In Java 8 interfaces default and static methods are major changes that allow to extend existing code without breaking anything. It should be the first step into Java 8.

What was before Java 8

  • Single inheritance of implementations (classes)
    You could extend only one class. This is still valid.
  • Multiple inheritance of types (interfaces)
    You could implement one or more interfaces. Still valid.
  • Interfaces cannot provide implementations
    You could add static final fields, specify methods signatures, but could not implement anything in interfaces. This has changed in Java 8!

Static methods in interfaces

They work in the same way as static methods in ordinary Java classes, so they cannot be overridden. For example you can create a static factory method (most common case) in an interface:

package com.farenda.java.lang;

import java.util.Date;

public interface NewInterface {

    static Date now() {
        return new Date();
    }
}

And call it like this: NewInterface.now()

Default methods in interfaces

Default methods in Java 8 interfaces provide real implementations and can be overridden in classes implementing them. So, interfaces became something like abstract classes, except that their methods are public (abstract classes can have public, protected, default, and private) and you can implement multiple interfaces, whereas only one abstract class can be extended.

Let’s look at an example:

package com.farenda.java.lang;

import java.util.Date;

public interface NewInterface {

    default String formatDate(Date date) {
        return date.toString();
    }

    default int sum(int a, int b) {
        return a + b;
    }
}

Same default method in two interfaces

If a class implements interfaces with the same signature of default method, then it must be overridden or the compiler will show the following error:

Error:(3, 8) java: class com.farenda.java.lang.MultiType
                   inherits unrelated defaults for
                   formatDate(java.util.Date) from types
                   com.farenda.java.lang.NewInterface and
                   com.farenda.java.lang.AnotherInterface

Purpose of default methods in interfaces

The purpose of default methods is to allow programmers to extend their libraries without breaking existing code bases. Notice how many new methods have been added to java.util.Collection and java.util.Map interfaces without breaking classes implementing them. You will see more use in articles about Java 8 Lambdas and Streams!

Example interface in Java 8

The following interface is a sample interface taken from JDK 8. It has abstract method, default methods, and static method. All in one:

package java.util.function;

import java.util.Objects;

@FunctionalInterface
public interface Function<T, R> {

    R apply(T t); // abstract method

    default <V> Function<V, R> compose(Function<V, T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    default <V> Function<T, V> andThen(Function<R, V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

    static <T> Function<T, T> identity() {
        return t -> t;
    }
}

@FunctionalInterface and Lambdas are covered in other Java Tutorials.

References:

Share with the World!