Java 8 thêm vào interface 2 cú pháp mới — đảo ngược nguyên tắc "interface không có code".
1. default method:
interface Vehicle {
String name();
default void start() { System.out.println(name() + " started"); }
}
class Car implements Vehicle {
public String name() { return "Car"; }
// start() — không cần override, dùng default
}Kế thừa, override được nếu cần behavior khác.
2. static method: utility gắn vào interface, gọi qua tên interface, không kế thừa.
Comparator<Integer> rev = Comparator.reverseOrder();Java 9+ thêm private method: helper cho default, không expose ra ngoài.
Vì sao Java 8 thêm default? Để thêm stream() vào Collection interface (17 năm tuổi) mà không break implementation cũ. Với default → cung cấp implementation chung, class cũ không cần biết.
Quy tắc:
- ✅ Default cho API evolution (thêm method tiện lợi không break).
- ✅ Default cho method tính được từ method khác (default boolean isEmpty() { return size() == 0; }).
- ❌ Đừng dùng default thay abstract class — cần state thì dùng abstract class.
- ❌ Interface phụ thuộc nhiều default = dấu hiệu nên là abstract class.
Functional interface vẫn yêu cầu đúng 1 abstract method — default/static không tính.
Java 8 added two new interface constructs — reversing the "interfaces have no code" rule.
1. default methods:
interface Vehicle {
String name();
default void start() { System.out.println(name() + " started"); }
}
class Car implements Vehicle {
public String name() { return "Car"; }
// start() — no override needed, uses default
}Inherited, overridable if a subclass wants different behaviour.
2. static methods: utilities attached to the interface, called via the interface name, not inherited.
Comparator<Integer> rev = Comparator.reverseOrder();Java 9+ added private methods: helpers for defaults, not exposed externally.
Why Java 8 added defaults? To add stream() to the 17-year-old Collection interface without breaking existing implementations. With defaults, the interface provides a shared implementation; old classes do not need to know.
Rules:
- ✅ Default for API evolution (add convenience methods without breaking).
- ✅ Default for derivable methods (default boolean isEmpty() { return size() == 0; }).
- ❌ Do not use defaults to replace abstract classes — if you need state, use an abstract class.
- ❌ Interfaces relying heavily on defaults = a sign you really want an abstract class.
Functional interfaces still require exactly one abstract method — defaults/statics do not count.