Skip to content

Latest commit

 

History

History
219 lines (188 loc) · 6.64 KB

create_and_use_methods_in_interfaces.md

File metadata and controls

219 lines (188 loc) · 6.64 KB

Create and use methods in interfaces

Java 9 introduced private methods and private static methods in interfaces. So an interface can now have 7 different things:

  • constant variables
  • abstract methods
  • nested types
  • default methods
  • static methods
  • private methods
  • private static methods

The private methods are only accessible within an interface only and cannot be accessed or inherited from the interface to another interface or class.

Constant variables

Interface variables are static because Java interfaces cannot be instantiated in their own right; the value of the variable must be assigned in a static context in which no instance exists.

The final modifier ensures the value assigned to the interface is a true constant that cannot be re-assigned

public interface IGreeting {
  String GREETING = "Hello from the interface";
}
public class Example {
  public static void main(String[] args){
    System.out.println(IGreeting.GREETING);
  }
}

Code Sample

abstract methods

Every method declaration in an interface with body represented by a semicolon is implicitly public and abstract

It is a compile-time error if a method declaration that contains the keyword abstract also contains any one of the keywords private, static, final, native, strictfp, or syncronized

It would be impossible for a class to implement a private abstract method, because private methods are not inherited by subclasses

public interface Greeting {
  void sayHello();
}
public class Example {
  public static void main(String[] args){
    GreetingImpl greeting = () -> {
      System.out.println("Hello");
    };
    greeting.sayHello();
  }
}

nested types

Interfaces may contain member type declarations. A member type declaration is an interface is implicitly static and public

public interface Greeting {
  class GreetingException extends Exception {
    public GreetingException() { super(); }
  }
  
  interface EnglishGreeting {
    String GREETING = "Hi there";
  }
}
public class Example {
  public static void main(String[] args){
    try {
      System.out.println(Greeting.EnglishGreeting.GREETING);
    } catch (Greeting.GreetingException ex){
      // do something useful with the caught exception
    }
  }
}

Code Sample

default methods

Default methods are declared with the default keyword at the beginning of the method signature and they provide an implementation.

As such they enable you to add new functionality to the interfaces of your library, ensuring backwards compatibility as classes already implementing your interface do not have to provide a implementation of the new method.

An implementing class can override the default implementation provided by the interface

public interface Greeting {
  default void sayHello(){
    System.out.println("Hello");
  };
}
public class Example {
  public static void main(String[] args){
    GreetingImpl greeting = new Greeting(){
      //We don't need to override the default method
    };
    greeting.sayHello();
  }
}

Code Sample

If a class implements two interfaces, both of which have a default method with the same name and parameter types then you must resolve the conflict

public interface GreetingEnglish{
  default void sayHello(){
      System.out.println("Hello");
    };
}
public interface GreetingFrench{
  default void sayHello(){
      System.out.println("Bonjour");
    };
}
public class Example implements GreetingEnglish, GreetingFrench {
  //WILL NOT COMPILE. You must resolve the conflict on sayHello()
}

In the example above you should either provide a sayHello() method in the Example class and implement your own greeting or delegate to one of the conflicting methods like so:

public class Example implements GreetingEnglish, GreetingFrench {
  @Override
  public void sayHello(){
    GreetingFrench.super.sayHello();
  }
}

static methods

Like static methods in classes, you can specify that a method definition in a interface is a static method with the static keyword at the beginning of the method signature

A static method can be invoked from other static or default methods

public interface Greeting {
  static void sayHello() {
    System.out.println("Hello");
  }
}
public class Example {
  public static void main(String[] args){
    Greeting.sayHello();
  }
}

A static method cannot be overridden or changed in the implementing class

A static method cannot be shadowed, neither as part of the interface, or part of the implementing class

Code Sample

private methods

private methods should improve code reusability inside interfaces and encapsulation. You can use private methods to share code among default methods without exposing it to classes implementing the interface

public interface Greeting {
 default void greet(){
   System.out.print(getGreeting());
 }
 
 private String getGreeting(){
   return "Hello";
 }
}

Rules for private methods in interfaces:

  • The private modifier must be used to define them
  • The private and abstract modifiers cannot be used together
  • The private and default modifiers cannot be used together. default methods are always public
  • The private methods must contain an implementation body

Code Sample

private static methods

private static methods allow you to extract common code into a private static method but not into an instance method that would require you to create a instance of the type to use

A private static method can be called from instance (i.e default or private non-static) methods or static method inside the interface

A private non-static method is not allowed to be called from static or private static methods within the interface

public interface Greeting {
  static void sayHello(){
    System.out.println(getGreeting());
  }
  
  private static String getGreeting(){
    return "Hello";
  } 
} 

Code Sample

Previous Next