An interface is a contract that only determines “what a class can do.” Java classes can only inherit from one parent, but multiple interfaces (implements) can be implemented, allowing for free combination of actions.
Learning Objectives
- Define the contract with the
interfacekeyword - Implement the interface with
implements - Know the meaning of JDK 8+
defaultmethod - Learn the concept of functional interface (
@FunctionalInterface) (see Part 18 for detailed usage)
Key concepts
1) Interface definition
public interface Printable {
void print(); //public abstract is the default
}
- All methods default to
public abstract - All fields are
public static final(constant) - No need to write separate keywords
2) implements
public class Document implements Printable {
private String text;
public Document(String t) { this.text = t; }
@Override
public void print() {
System.out.println(">> " + text);
}
}
Multiple interfaces can be implemented simultaneously: implements A, B, C.
3) default method
public interface Greeter {
String name();
default String greet() {
return "Hello, " + name();
}
}
By providing a default implementation, adding methods to an interface does not break the existing implementation class.
4) Functional interface
@FunctionalInterface
interface Calc {
int apply(int a, int b);
}
An interface with exactly 1 abstract method. It can be briefly implemented with lambda.
Calc add = (a, b) -> a + b;
add.apply(2, 3); // 5
See as example
Example 1 — Printable.java + Document.java: Interface implementation
Printable.java:
public interface Printable {
void print();
}
Document.java:
public class Document implements Printable {
private String text;
public Document(String t) { this.text = t; }
@Override
public void print() {
System.out.println(">> " + text);
}
public static void main(String[] args) {
Printable p = new Document("Hello, Interface!");
p.print();
}
}
Execution result
>> Hello, Interface!
Memo: If you leave the variable type as an interface, it can be replaced with any implementation.
Example 2 — MultipleInterface.java: Implementing multiple interfaces
public class MultipleInterface {
interface Flyable { void fly(); }
interface Swimmable { void swim(); }
static class Duck implements Flyable, Swimmable {
@Override public void fly() { System.out.println("ducks fly"); }
@Override public void swim() { System.out.println("duck swimming"); }
}
public static void main(String[] args) {
Duck d = new Duck();
d.fly();
d.swim();
Flyable f = d;
Swimmable s = d;
f.fly();
s.swim();
}
}
Execution result
ducks fly
duck swimming
ducks fly
duck swimming
Note: The same object can be viewed through different interfaces.
Example 3 — DefaultMethod.java : default method
public class DefaultMethod {
interface Greeter {
String name();
default String greet() { return "Hello, " + name(); }
}
static class Korean implements Greeter {
public String name() { return "exponent"; }
}
static class English implements Greeter {
public String name() { return "John"; }
@Override
public String greet() { return "Hi, " + name(); }
}
public static void main(String[] args) {
System.out.println(new Korean().greet());
System.out.println(new English().greet());
}
}
Execution result
Hello, Jisoo
Hi, John
Note: The default method can be used as is or overridden by children.
Example 4 — FunctionalDemo.java: Functional interface + lambda
public class FunctionalDemo {
@FunctionalInterface
interface Calc {
int apply(int a, int b);
}
public static void main(String[] args) {
Calc add = (a, b) -> a + b;
Calc mul = (a, b) -> a * b;
Calc max = (a, b) -> a > b ? a : b;
System.out.println("add(2,3)=" + add.apply(2, 3));
System.out.println("mul(2,3)=" + mul.apply(2, 3));
System.out.println("max(2,3)=" + max.apply(2, 3));
}
}
Execution result
add(2,3)=5
mul(2,3)=6
max(2,3)=3
Memo: Lambda is covered in detail in Part 18. Here, just keep in mind the concept of “functional interface = object of lambda”.
Common Mistakes
- Confusion between
implementsandextends(interface isimplements) - Interface methods are not implemented → the class becomes an abstract class.
defaultmethod conflict (overriding is required when the same signature is present in both interfaces)- Two abstract methods in functional interface (
@FunctionalInterfacecompilation error) - Trying to put an instance field on an interface (not possible)
Cleanup
- An interface is a contract of “what you can do”
- Class multiple inheritance
- The
defaultmethod is a safety net for interface extensions. - Functional interfaces are very powerful when combined with lambdas.
Try it yourself
cd 02_Object-Oriented/10_Interface/src
javac Printable.java Document.java
java Document