인터페이스에 메소드 선언이 아니라 구현체를 제공하는 방법
해당 인터페이스를 구현한 클래스를 깨트리지 않고 새 기능을 추가할 수 있다.
public class DefaultFoo implements Foo {
private String name;
@Override
public void printName() {
System.out.println("DefaultFoo");
}
@Override
public String getName() {
return this.name;
}
}
...
public interface Foo {
void printName();
/**
* @implSpec 이 구현체는 getName()으로 가져온 문자열을 대문자로 바꿔 출력한다.
*/
default void printNameUpperCase() {
System.out.println(getName().toUpperCase());
}
String getName();
}
기본 메소드는 구현체가 모르게 추가된 기능으로 그만큼 리스크가 있다.
Object가 제공하는 기능 (equals, hasCode)는 기본 메소드로 제공할 수 없다.
본인이 수정할 수 있는 인터페이스에만 기본 메소드를 제공할 수 있다.
인터페이스를 상속받는 인터페이스에서 다시 추상 메소드로 변경할 수 있다.
public interface Bar extends Foo {
void printNameUpperCase();
}
인터페이스 구현체가 재정의 할 수도 있다.
해당 타입 관련 헬퍼 또는 유틸리티 메소드를 제공할 때 인터페이스에 스태틱 메소드를 제공할 수 있다.
static void printAnything() {
System.out.println("Foo");
}
https://docs.oracle.com/javase/tutorial/java/IandI/nogrow.html
https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
자바 8에서 추가한 기본 메소드로 인한 API 변화
Iterable의 기본 메소드
forEach()
List<String> name = new ArrayList<>();
name.add("wooksang");
name.add("today8934");
name.add("toby");
name.add("foo");
name.forEach(s -> {
System.out.println(s);
});
name.forEach(System.out::println);
spliterator()
Spliterator<String> spliterator = name.spliterator();
while (spliterator.tryAdvance(System.out::println));
Collection의 기본 메소드
Comparator의 기본 메소드 및 스태틱 메소드
https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html
https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html
https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html
https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html