인터페이스의 Default 및 Static 메서드
Coddy Java 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 87개 중 37번째.
원래 인터페이스는 구현이 없는 추상 메서드만 포함할 수 있었습니다. Java 8부터 인터페이스는 디폴트 메서드(default methods)와 정적 메서드(static methods)를 포함할 수 있는 기능을 갖게 되어 더욱 유연해졌습니다.
디폴트 메서드(default method)는 default 키워드를 사용하여 인터페이스 내에서 직접 구현을 제공합니다. 이 인터페이스를 구현하는 클래스들은 이 동작을 자동으로 상속받지만, 필요한 경우 이를 오버라이드(재정의)할 수 있습니다:
public interface Drawable {
void draw();
default void display() {
System.out.println("Displaying on screen...");
draw();
}
}Drawable을 구현하는 모든 클래스는 display() 메서드를 자동으로 얻게 됩니다. 이는 이미 해당 인터페이스를 구현하고 있는 클래스들을 손상시키지 않으면서 기존 인터페이스에 새로운 메서드를 추가하는 데 특히 유용합니다.
인터페이스의 정적 메서드는 클래스의 정적 메서드와 유사하게 동작합니다. 이들은 인터페이스 자체에 속하며 인터페이스 이름을 사용하여 호출됩니다:
public interface MathOperations {
static int add(int a, int b) {
return a + b;
}
}
// 사용법
int result = MathOperations.add(5, 3);정적 인터페이스 메서드는 오버라이드될 수 없으며 구현 클래스에 상속되지 않습니다. 이들은 인터페이스의 목적과 관련된 유틸리티 메서드에 유용합니다.
클래스가 동일한 디폴트 메서드 시그니처를 가진 두 개의 인터페이스를 구현하는 경우, 해당 클래스는 충돌을 해결하기 위해 그 메서드를 반드시 오버라이드해야 합니다.
챌린지
쉬움인터페이스의 디폴트(default) 메서드와 정적(static) 메서드를 모두 보여주는 메시징 시스템을 구축해 보겠습니다. 구현 클래스가 직접 사용하거나 필요에 따라 사용자 정의할 수 있는 내장 기능이 포함된 인터페이스를 만들 것입니다.
코드는 다음 네 개의 파일로 구성됩니다:
Messenger.java: 모든 메시징 서비스를 나타내는 인터페이스를 정의합니다. void를 반환하는 추상 메서드sendMessage(String message)를 선언해야 합니다.[TIMESTAMP]를 출력한 후sendMessage(message)를 호출하는sendWithTimestamp(String message)라는 디폴트 메서드를 추가하세요. 또한 메시지를 대문자로 변환하여 반환하는formatMessage(String message)라는 정적 메서드를 포함하세요.EmailMessenger.java:Messenger를 구현하는 클래스를 만듭니다.recipient필드(String)를 가집니다. 수신자를 초기화하는 생성자를 포함하세요.Email to [recipient]: [message]를 출력하도록sendMessage()를 구현하세요. 이 클래스는 디폴트sendWithTimestamp()메서드를 그대로 사용합니다.SMSMessenger.java:Messenger를 구현하는 또 다른 클래스를 만듭니다.phoneNumber필드(String)를 가집니다. 전화번호를 초기화하는 생성자를 포함하세요.SMS to [phoneNumber]: [message]를 출력하도록sendMessage()를 구현하세요. 기본 타임스탬프 동작 대신[URGENT]를 출력한 후sendMessage(message)를 호출하도록 디폴트sendWithTimestamp()메서드를 오버라이드하세요.Main.java: 모든 것을 하나로 모아 디폴트 및 정적 인터페이스 메서드를 시연합니다. 이메일 수신자, 전화번호, 메시지의 세 가지 입력을 받습니다. 먼저 정적 메서드인Messenger.formatMessage()를 사용하여 메시지 형식을 지정하고 저장합니다. 그런 다음 EmailMessenger와 SMSMessenger를 생성합니다. 각 메신저에 대해 형식화된 메시지로sendWithTimestamp()를 호출하세요. EmailMessenger는 기본 구현을 사용하는 반면 SMSMessenger는 오버라이드된 버전을 사용하는 것을 확인할 수 있습니다.
이메일 수신자(String), 전화번호(String), 메시지(String)의 세 가지 입력을 받게 됩니다.
출력은 각 메신저당 두 줄씩 총 네 줄이 되어야 합니다. EmailMessenger는 기본 타임스탬프 접두사를 표시하고, SMSMessenger는 사용자 정의된 긴급(urgent) 접두사를 표시합니다. 두 메신저 모두 정적으로 형식화된(대문자) 메시지를 사용하게 됩니다!
치트 시트
Java 8부터 인터페이스는 추상 메서드 외에도 디폴트 메서드(default methods)와 정적 메서드(static methods)를 포함할 수 있습니다.
디폴트 메서드는 default 키워드를 사용하여 인터페이스 내에서 직접 구현을 제공합니다. 인터페이스를 구현하는 클래스는 이 동작을 자동으로 상속받지만, 필요한 경우 이를 오버라이드(override)할 수 있습니다:
public interface Drawable {
void draw();
default void display() {
System.out.println("Displaying on screen...");
draw();
}
}인터페이스의 정적 메서드는 인터페이스 자체에 속하며 인터페이스 이름을 사용하여 호출됩니다. 이 메서드들은 오버라이드할 수 없으며 구현 클래스에 상속되지 않습니다:
public interface MathOperations {
static int add(int a, int b) {
return a + b;
}
}
// Usage
int result = MathOperations.add(5, 3);클래스가 동일한 디폴트 메서드 시그니처를 가진 두 개의 인터페이스를 구현하는 경우, 해당 클래스는 충돌을 해결하기 위해 해당 메서드를 반드시 오버라이드해야 합니다.
직접 해보기
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 입력 읽기
String emailRecipient = scanner.nextLine();
String phoneNumber = scanner.nextLine();
String message = scanner.nextLine();
// TODO: Messenger.formatMessage()를 사용하여 메시지 형식을 지정하고 저장하세요
// TODO: 이메일 수신자로 EmailMessenger를 생성하세요
// TODO: 전화번호로 SMSMessenger를 생성하세요
// TODO: 형식화된 메시지와 함께 EmailMessenger에서 sendWithTimestamp()를 호출하세요
// TODO: 형식화된 메시지와 함께 SMSMessenger에서 sendWithTimestamp()를 호출하세요
}
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
4상속
상속의 기초 (extends)super 키워드메서드 오버라이딩 (@Override)생성자 체이닝Object 클래스단일 및 다중 레벨 상속다중 클래스 상속이 불가능한 이유요약 - 직원 계층 구조6인터페이스와 추상 클래스
인터페이스 소개인터페이스 구현하기다중 인터페이스 구현인터페이스의 Default 및 Static 메서드추상 클래스 vs 인터페이스함수형 인터페이스복습 - 결제 시스템