Menu

자바 인터페이스: 계약 정의와 implements

자바 인터페이스란 무엇인지, 어떻게 정의하고 구현하는지, default 메서드와 static 메서드, 그리고 인터페이스가 추상 클래스와 어떻게 다른지 살펴봅니다.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

인터페이스는 계약입니다

인터페이스는 클래스가 어떻게 하는지는 말하지 않고 무엇을 할 수 있는지를 선언합니다. 이는 구현하는 모든 클래스가 이행하기로 약속하는 메서드 시그니처의 목록입니다. 핵심은 결합도를 낮추는 것입니다. 코드는 인터페이스 타입과 작업하면 되고 그 뒤에 어떤 구체 클래스가 있는지 신경 쓰지 않아도 됩니다.

Circle implements ShapeCircleareaperimeter 를 정의해야 함을 의미합니다. 일단 정의하고 나면 CircleShape 이며, Shape 타입 변수에 담을 수 있습니다.

여러 클래스, 하나의 타입

여러 관련 없는 클래스가 동일한 인터페이스를 구현할 때 그 위력이 드러납니다. Shape 를 기준으로 작성된 코드는 그것들을 모두 처리합니다.

이 반복문은 "이것이 Circle 인가 Rectangle 인가?"를 절대 묻지 않습니다. 그저 area() 를 호출하고 계약을 신뢰합니다. 나중에 Triangle 을 추가하더라도 여기서는 아무런 변경이 필요하지 않습니다.

여러 인터페이스 구현하기

클래스는 단 하나의 클래스만 상속하지만, 인터페이스는 원하는 만큼 구현할 수 있습니다. 이것이 자바가 동작의 "다중 상속"을 안전하게 구현하는 방식입니다.

implements 뒤에 인터페이스를 쉼표로 구분해 나열합니다. 클래스는 그 모두를 만족해야 합니다.

default 메서드와 static 메서드

자바 8부터 인터페이스는 메서드 본문을 담을 수 있습니다. default 메서드는 구현 클래스가 거저 상속하는(그리고 재정의할 수 있는) 기성 구현을 제공합니다.

default 메서드는 인터페이스가 진화할 수 있게 해 줍니다. 기존의 모든 구현체를 깨뜨리지 않고도 메서드를 추가할 수 있습니다. 반면 static 인터페이스 메서드Comparator.naturalOrder() 처럼 인터페이스 자체에서 호출하는 유틸리티입니다.

상수

인터페이스의 필드는 암묵적으로 public static final 입니다. 이것들은 인스턴스 상태가 아니라 상수입니다.

interface Physics {
    double GRAVITY = 9.81;   // automatically public static final
}

인터페이스는 전통적으로 객체별 상태를 가지지 않습니다. 인스턴스 필드가 없다는 점은 인터페이스를 클래스와 구분 짓는 요소 중 하나입니다.

함수형 인터페이스

추상 메서드를 정확히 하나만 가진 인터페이스는 함수형 인터페이스이며, 클래스 전체 대신 람다 표현식으로 구현할 수 있습니다.

이는 자바의 람다와 java.util.function 타입들(Function, Predicate, Supplier 등)의 기반입니다. @FunctionalInterface 애너테이션은 의도를 명시적으로 드러내고, 컴파일러가 단일 메서드 규칙을 강제하도록 합니다.

인터페이스 vs 추상 클래스

둘 다 추상화를 대상으로 프로그래밍할 수 있게 해 주는데, 그렇다면 언제 어느 것을 선택해야 할까요?

  • 인터페이스 - 관련 없는 클래스들이 공유할 수 있는 기능. BirdAirplane 은 둘 다 Flyable 일 수 있습니다. 클래스는 여러 개를 구현할 수 있습니다. 인스턴스 상태가 없습니다.
  • 추상 클래스 - 밀접하게 관련된 클래스 간에 공유되는 상태와 코드. CatDog 은 둘 다 Animal 을 상속해 공통 필드와 부분적으로 구현된 메서드를 물려받습니다. 클래스는 하나만 상속합니다.

흔한 패턴은 둘을 결합합니다. 인터페이스가 계약을 정의하고, 추상 클래스가 반복되는 부분을 구현해, 구체 하위 클래스는 고유한 세부 사항만 채우면 됩니다.

다음: 추상 클래스

인터페이스는 상태 없이 동작을 정의합니다. 추상 클래스는 인터페이스와 완전한 클래스의 중간에 위치합니다. 구현되지 않은 메서드를 선언할 수 있고 동시에 필드와 생성자를 가질 수 있습니다. 그것이 다음 페이지의 주제입니다.

자주 묻는 질문

자바에서 인터페이스란 무엇인가요?

인터페이스는 계약입니다. 즉, 클래스가 제공하기로 약속하는 메서드 시그니처(와 상수)의 집합입니다. 클래스가 무엇을 할 수 있는지는 말하지만 어떻게 하는지는 말하지 않습니다. 클래스는 implements 키워드를 사용해 인터페이스를 받아들이며, 인터페이스가 선언한 모든 추상 메서드에 대해 본문을 제공해야 합니다. 인터페이스를 사용하면 서로 관련 없는 클래스들을 공통 타입을 통해 호환되게 사용할 수 있습니다.

자바에서 인터페이스와 추상 클래스의 차이는 무엇인가요?

클래스는 여러 인터페이스를 구현할 수 있지만 상속(extends)할 수 있는 (추상) 클래스는 하나뿐입니다. 인터페이스는 전통적으로 인스턴스 상태를 가지지 않고 동작만 선언하는 반면, 추상 클래스는 필드, 생성자, 부분적으로 구현된 로직을 가질 수 있습니다. 서로 관련 없는 여러 클래스가 공유할 수 있는 기능을 정의하려면 인터페이스를 사용하고, 밀접하게 관련된 하위 클래스 간에 공통 상태와 코드를 공유하려면 추상 클래스를 사용하세요.

자바 인터페이스가 메서드 본문을 가질 수 있나요?

네, 자바 8부터 가능합니다. default로 표시된 인터페이스 메서드는 구현 클래스가 상속하는(그리고 재정의할 수 있는) 본문을 제공하며, static 인터페이스 메서드는 인터페이스 자체에서 호출할 수 있는 유틸리티 동작을 제공합니다. 일반 인터페이스 메서드는 여전히 추상적이며 -시그니처뿐- 구현 클래스가 이를 정의해야 합니다.

Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기