Java 8은 인터페이스에 디폴트 메서드(Default Method)라는 완전히 새로운 개념을 도입했습니다. 이 기능은 하위 호환성(Backward Compatibility)을 유지하기 위해 추가되었으며, 기존에 작성된 오래된 인터페이스들도 Java 8의 강력한 람다 표현식(Lambda Expression) 기능을 그대로 활용할 수 있도록 만들어 줍니다.
디폴트 메서드가 등장한 배경
Java 8 이전에는 인터페이스에 새로운 메서드를 추가하는 것이 매우 위험한 작업이었습니다. 인터페이스에 메서드를 하나라도 추가하면, 해당 인터페이스를 구현하는 모든 클래스가 새 메서드를 반드시 구현해야 했기 때문입니다.
기존 컬렉션 프레임워크의 문제점
대표적인 예로 List나 Collection 인터페이스를 들 수 있습니다. 이 인터페이스들은 forEach 메서드 선언을 가지고 있지 않았습니다. 만약 Java 8에서 단순히 forEach 메서드를 인터페이스에 추가했다면, 전 세계적으로 배포된 수많은 컬렉션 프레임워크 구현체들이 컴파일 오류를 일으키며 깨져버렸을 것입니다.
디폴트 메서드의 해결 방식
Java 8은 이 문제를 디폴트 메서드로 해결했습니다. List와 Collection 인터페이스는 forEach 메서드의 기본 구현체를 인터페이스 내부에 직접 가지게 되었고, 이 덕분에 해당 인터페이스를 구현하는 클래스들은 별도로 forEach를 재정의하지 않아도 됩니다.
public interface MyInterface {
// 디폴트 메서드 - 구현 클래스가 선택적으로 재정의 가능
default void printHello() {
System.out.println("Hello, Java 8!");
}
}
이처럼 디폴트 메서드는 인터페이스의 진화를 가능하게 하면서도, 기존 코드의 호환성을 깨뜨리지 않는 우아한 방법을 제공합니다.
인터페이스의 정적 메서드
Java 8부터는 인터페이스 안에 정적(Static) 헬퍼 메서드도 정의할 수 있게 되었습니다. 이전 버전에서는 유틸리티 성격의 메서드를 별도의 유틸리티 클래스(예: Collections)에 두어야 했지만, 이제는 관련 로직을 인터페이스 자체에 응집력 있게 모아둘 수 있습니다.
public interface MyInterface {
// 정적 메서드 - 인터페이스 이름으로 직접 호출
static int add(int a, int b) {
return a + b;
}
}
// 호출 예시
int result = MyInterface.add(10, 20);
정리
Java 8의 인터페이스 개선 사항은 다음과 같이 요약할 수 있습니다.
- 디폴트 메서드: 인터페이스에 기본 구현을 제공하여, 구현 클래스가 필수적으로 재정의하지 않아도 되도록 함
- 정적 메서드: 인터페이스 내부에 헬퍼 메서드를 정의하여 유틸리티 로직의 응집도를 높임
- 하위 호환성 보장: 기존 구현체를 깨뜨리지 않고 람다 표현식과 스트림 API 같은 신규 기능을 기존 인터페이스에 통합 가능
이러한 변화 덕분에 Java 8은 기존 생태계와의 호환성을 유지하면서도 함수형 프로그래밍 스타일로 크게 진화할 수 있었습니다.