Before Java 8, interfaces couldn’t implement any code. With Java 8, interfaces can include default methods implementations and also static methods.
Default Methods
Default method is method implemented in interface marked by the modifier default. These methods can be called from all classes implementing the interface. What is it good for? Let’s imagine a game with a lot of heroes that have can do some actions. E.g. going left and right. After while add a new action, for example jumping. Now we have to implement this action in all methods. And maybe this action is same for all heroes or we don’t need this action to be used by all heroes. The implementation of second option could look like this:
public interface HeroActions { void goLeft(); void goRight(); default void jump() { throw new UnsupportedOperationException(); } }
Now we can implement our heroes. First of them know how to jump so we override default method.
public class ManHero implements HeroActions { @Override public void goLeft() { System.out.println("Going left"); } @Override public void goRight() { System.out.println("Going right"); } @Override public void jump() { System.out.println("Jumping"); } }
Second is Wasp and jumping make no sense, so the method is not overridden.
public class WaspHero implements HeroActions { @Override public void goLeft() { System.out.println("Flying left"); } @Override public void goRight() { System.out.println("Flying right"); } }
Now we can call all these actions on our heroes. If we call jump on WaspHero object by accident, an exception will be thrown.
WaspHero hero = new WaspHero(); hero.goLeft(); hero.jump();
Static methods
Static methods are are are often used as helper methods. Now they can be defined not only in classes but also in interfaces. They are associated with the interface, not object that implements them. Let’s add the static method to generate really cool name to our interface:
static String generateCoolName() { Random rand = new Random(); int top = 3; char chr; String name = ""; for (int i = 0; i <= top; i++) { chr = (char) (rand.nextInt(25) + 97); name = chr + name; } return name.toUpperCase(); }
You can call this function from anywhere this way:
System.out.println(HeroActions.generateCoolName());
Default method vs Abstract class in Java 8
In Java 8 interface with default methods can look similar to the abstract class. But there are still differences. The abstract method can define the constructor. Also, abstract classes are more structured and can hold a state.
In Abstract class we can redeclare default method as abstract to force subclasses to override it.
Default and static methods in Kotlin interfaces
In Kotlin both default and static interface methods can be used. It only looks slightly different:
interface HeroActions { fun goLeft() fun goRight() fun jump() { throw UnsupportedOperationException() } companion object { fun generateCoolName(): String { val rand = Random() val top = 3 var chr: Char var name = "" for (i in 0..top) { chr = (rand.nextInt(25) + 97).toChar() name = chr + name } return name.toUpperCase() } } }
There is no default keyword for default implementation, you simply provide the implementation. And static method in Kotlin needs to go into companion object.