[Java] 67. 디폴트 메서드

2025. 7. 4. 23:57·Java/Modern Java(8~)

 

디폴트 메서드

#Java/adv3


디폴트 메서드가 등장한 이유

  • 자바 8에서 디폴트 메서드(default method) 가 등장하기 전에는 인터페이스에 메서드를 새로 추가하는 순간, 이미 배포된 기존 구현 클래스들이 해당 메서드를 구현하지 않았기 때문에 전부 컴파일 에러를 일으키게 되는 문제가 있었다.
  • 디폴트 메서드는 이러한 문제를 해결하기 위해 등장했다.
  • 자바 8부터는 인터페이스에서 메서드 본문을 가질 수 있도록 허용해 주어, 기존 코드를 깨뜨리지 않고 새 기능을 추가할 수 있게 되었다.

디폴트 메서드로 문제 해결
자바 8부터 이러한 하위 호환성 문제를 해결하기 위해 디폴트 메서드가 추가되었다. 인터페이스에 메서드를 새로 추가하면서, 기본 구현을 제공할 수 있는 기능이다.
예를 들어, Notifier 인터페이스에 scheduleNotification() 메서드를 default 키워드로 작성하고 기본 구현을 넣어두면, 구현 클래스들은 이 메서드를 굳이 재정의하지 않아도 된다.

package defaultmethod.ex2;

import java.time.LocalDateTime;

public interface Notifier {
    // 알림을 보내는 기본 기능
    void notify (String message);

    // 신규 기능 추가
    // void scheduleNotification(String message, LocalDateTime scheduleTime); // 주석

    // default 키워드를 사용해 기본 구현 제공
    default void scheduleNotification(String message, LocalDateTime scheduleTime) {
        System.out.println("[기본 스케줄링] message: " + message + ", time: " + scheduleTime);
    }
}
  • 구현 클래스에서는 필요한 경우에만 재정의하면 됨
  • 재정의하지 않으면 인터페이스에 작성한 기본 구현이 그대로 사용됨

디폴트 메서드 소개

자바는 처음부터 인터페이스와 구현을 명확하게 분리한 언어였고, 인터페이스는 구현 없이 메서드의 시그니처만을 정의하는 용도로 사용되었다.

  • 인터페이스 목적: 코드의 계약(Contract)을 정의하고, 클래스가 어떤 메서드를 반드시 구현하도록 강제하여 명세와 구현을 분리하는 것이 주된 목적이었다.
  • 엄격한 규칙: 인터페이스에 선언되는 메서드는 기본적으로 모두 추상 메서드(abstract method)였으며, 인터페이스 내에서 구현 내용을 포함할 수 없었다. 오직 static final 필드와 abstract 메서드 선언만 가능했다.
  • 결과: 이렇게 인터페이스가 엄격하게 구분됨으로써, 클래스는 여러 인터페이스를 구현(implements)할 수 있게 되고, 각각의 메서드는 클래스 내부에서 구체적으로 어떻게 동작할지를 자유롭게 정의할 수 있었다. 이를 통해 객체지향적인 설계와 다형성을 극대화할 수 있었다.

만약 자바가 버전 업을 하면서 해당 인터페이스에 새로운 기능을 추가한다면 어떻게 될까? 전 세계에서 자바 Application에서 컴파일 오류가 발생하게 되버린다. 이런 문제를 방지하기 위해 자바는 하위호환성을 그 무엇보다 큰 우선순위에 둔다.
결국 인터페이스의 이런 엄격한 규칙 때문에, 그 동안 자바 인터페이스에 새로운 기능을 추가하지 못하는 일이 발생하게 되었다.


이런 문제를 해결하기 위해 자바 8에서 디폴트 메서드가 도입되었다.

  • 하위 호환성(Backward Compatibility) 보장: 인터페이스에 새로운 메서드를 추가하더라도, 기존 코드가 깨지지 않도록 하기 위한 목적으로 디폴트 메서드가 도입되었다. 인터페이스에 디폴트 구현(기본 구현)을 제공하면, 기존에 해당 인터페이스를 구현하던 클래스들은 추가로 재정의하지 않아도 정상 동작하게 된다.
  • 라이브러리 확장성: 자바가 제공하는 표준 라이브러리에 정의된 인터페이스(예: Collection, List)에 새 메서드를 추가하면서, 사용자들이나 서드파티 라이브러리 구현체가 일일이 수정하지 않아도 되도록 만들었다. 이를 통해 자바 표준 라이브러리 자체도 적극적으로 개선할 수 있게 되었다.
    • 예: List 인터페이스에 sort(...) 메서드가 추가되었지만, 기존의 모든 List 구현체를 수정하지 않아도 된다.
  • 람다와 스트림 API 연계: 자바 8에서 함께 도입된 람다(Lambda)와 스트림(Stream) API를 보다 편리하게 활용하기 위해 인터페이스에서 구현 로직을 제공할 필요가 있었다.
    • Collection 인터페이스에 stream() 디폴트 메서드 추가
    • Iterable 인터페이스에 forEach 디폴트 메서드 추가
  • 설계 유연성 향상: 디폴트 메서드를 통해 인터페이스에서도 일부 공통 동작 방식을 정의할 수 있게 되었다. 이는 추상 클래스와의 경계를 어느 정도 유연하게 만들지만, 동시에 지나치게 복잡한 기능을 인터페이스에 넣는 것은 오히려 설계를 혼란스럽게 만들 수 있으므로 주의해야 한다.


디폴트 메서드의 올바른 사용법

  1. 하위 호환성을 위해 최소한으로 사용: 기존 구현 클래스가 많은게 아니라면 추상 메서드로 추가하자. 디폴트 메서드 남용은 코드 복잡도를 높일 수 있다.
  2. 인터페이스는 여전히 추상화의 역할: 인터페이스에 로직을 넣을 수 있지만, 로직은 가능한 별도로 두고 계약의 역할에 충실!
  3. 다중 상속(충돌) 문제 어떤 인터페이스의 디폴트 메서드 쓸 것인지 명시
    1. 직접 구현
    2. A.super.hello();
    3. B.super.hello();
  4. 디폴트 메서드에 상태(state)를 두지 않기

Ref) 김영한의 실전 자바 - 고급 3편, 람다, 스트림, 함수형 프로그래밍 강의 | 김영한 - 인프런

'Java > Modern Java(8~)' 카테고리의 다른 글

[Java] 68. 병렬 스트림  (0) 2025.07.04
[Java] 66. Optional  (1) 2025.07.04
[Java] 65. 스트림 API3 - 컬렉터  (0) 2025.07.04
[Java] 64. 스트림 API2 - 기능  (0) 2025.07.04
[Java] 63. 스트림 API1 - 기본  (0) 2025.07.04
'Java/Modern Java(8~)' 카테고리의 다른 글
  • [Java] 68. 병렬 스트림
  • [Java] 66. Optional
  • [Java] 65. 스트림 API3 - 컬렉터
  • [Java] 64. 스트림 API2 - 기능
lumana
lumana
배움을 나누는 공간 https://github.com/bebeis
  • lumana
    Brute force Study
    lumana
  • 전체
    오늘
    어제
    • 분류 전체보기 (457)
      • Software Development (27)
        • Performance (0)
        • TroubleShooting (1)
        • Refactoring (0)
        • Test (8)
        • Code Style, Convetion (0)
        • DDD (0)
        • Software Engineering (18)
      • Java (71)
        • Basic (5)
        • Core (21)
        • Collection (7)
        • 멀티스레드&동시성 (13)
        • IO, Network (8)
        • Reflection, Annotation (3)
        • Modern Java(8~) (12)
        • JVM (2)
      • Spring (53)
        • Framework (12)
        • MVC (23)
        • Transaction (3)
        • AOP (11)
        • Boot (0)
        • AI (0)
      • DB Access (1)
        • Jdbc (1)
        • JdbcTemplate (0)
        • JPA (14)
        • Spring Data JPA (0)
        • QueryDSL (0)
      • Computer Science (130)
        • Data Structure (27)
        • OS (14)
        • Database (10)
        • Network (21)
        • 컴퓨터구조 (6)
        • 시스템 프로그래밍 (23)
        • Algorithm (29)
      • HTTP (8)
      • Infra (1)
        • Docker (1)
      • 프로그래밍언어론 (15)
      • Programming Language(Sub) (77)
        • Kotlin (1)
        • Python (25)
        • C++ (51)
        • JavaScript (0)
      • FE (11)
        • HTML (1)
        • CSS (9)
        • React (0)
        • Application (1)
      • Unix_Linux (0)
        • Common (0)
      • PS (13)
        • BOJ (7)
        • Tip (3)
        • 프로그래머스 (0)
        • CodeForce (0)
      • Book Review (4)
        • Clean Code (4)
      • Math (3)
        • Linear Algebra (3)
      • AI (7)
        • DL (0)
        • ML (0)
        • DA (0)
        • Concepts (7)
      • 프리코스 (4)
      • Project Review (6)
      • LegacyPosts (11)
      • 모니터 (0)
      • Diary (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
lumana
[Java] 67. 디폴트 메서드
상단으로

티스토리툴바