추상 클래스와 인터페이스
설명 영상 추상 클래스와 인터페이스 · 2:11
왜 배우는가: 추상 클래스와 인터페이스는 Java 객체지향 설계에서 상속 구조와 구현 강제 방식을 결정하는 기본 개념이다. 두 개념을 헷갈리면 클래스 다이어그램과 선언부를 잘못 작성하게 되므로 실무 설계 리뷰에서도 자주 확인된다. 기술사 시험에서는 UML 다이어그램과 Java 선언 코드를 함께 요구하는 문항으로 반복 출제되었다.
출제 이력: 제117회 4교시 2번, 제108회 2교시 1번
1. 한 줄 정의와 핵심 키워드
추상 클래스는 미구현 메서드를 포함할 수 있는 상속 전용 클래스이고, 인터페이스는 구현 클래스가 따라야 할 메서드 명세의 집합이다.
- 추상 클래스
- 인터페이스
- abstract 키워드
- implements 키워드
- 단일 상속
- 다중 구현
- 추상 메서드
2. 개념 풀이
쉬운 말로 하면, 추상 클래스는 "공통 골격은 이미 있고 세부 동작만 자식이 채우는 설계도"이다. 인터페이스는 "무엇을 할 수 있어야 하는지만 정해 둔 약속 목록"이다.
추상 클래스의 정식 정의는 추상 메서드를 하나 이상 포함하거나 abstract 키워드로 선언된 클래스이며, 인스턴스를 직접 생성할 수 없고 반드시 상속하여 사용한다. 추상 메서드는 몸체 없이 선언만 하며, 이를 포함한 클래스는 반드시 abstract로 선언해야 한다. 자식 클래스는 상속받은 추상 메서드를 모두 구현해야 하며, 그렇지 않으면 자식도 추상 클래스가 되어야 한다.
인터페이스의 정식 정의는 인터페이스(interface) 키워드로 선언하며, 구현 클래스에 공통으로 요구되는 메서드 시그니처와 상수를 정의하는 추상 타입이다. 클래스는 implements 키워드로 인터페이스를 구현한다. 인터페이스의 메서드는 명시하지 않아도 공개(public)이고 추상(abstract)으로 취급된다. 인터페이스의 필드는 자동으로 public static final 상수가 되므로 선언과 동시에 초기값을 주어야 한다.
두 개념의 가장 큰 차이는 상속 방식이다. 자바 클래스는 하나의 추상 부모만 가질 수 있으나, 한 클래스는 여러 인터페이스를 구현할 수 있다. 추상 클래스는 생성자, 인스턴스 변수, private·protected 멤버를 가질 수 있다. 인터페이스는 인스턴스 변수와 생성자를 가질 수 없다. Java 8 이후 인터페이스는 default 메서드와 static 메서드를 가질 수 있게 되었다.
설계 목적도 다르다. 추상 클래스는 공통 기능을 묶어 자식 클래스에 구현을 위임하는 데 쓰인다. 인터페이스는 서로 관계없는 클래스에 같은 기능 계약을 강제하는 데 쓰인다.
3. 등장 배경과 필요성
객체지향 설계에서는 상속을 통한 코드 재사용이 강력하지만, 자바는 클래스의 다중 상속을 허용하지 않는다. 이 제약을 보완하기 위해 여러 기능 계약을 여러 인터페이스로 묶어 구현하는 방식이 도입되었다. 그 결과 상속은 "is-a" 관계와 공통 구현에, 인터페이스는 "can-do" 계약에 나누어 쓰는 설계 원칙이 자리 잡았다.
추상 클래스는 여러 자식 클래스에 공통된 상태와 동작을 한곳에 두면서, 자식마다 달라야 하는 동작만 추상 메서드로 남겨 두기 위해 필요하다. 이렇게 하면 공통 코드 중복을 줄이고 상위 타입으로 자식 객체를 다루는 다형성을 확보할 수 있다.
인터페이스는 구현 세부를 숨기고 호출 측과 구현 측을 분리하기 위해 필요하다. 호출하는 쪽은 인터페이스 참조만 알면 되므로, 구현 객체가 바뀌어도 호출 코드를 고칠 필요가 없다. 이는 결합도를 낮추고 시험·교체를 쉽게 한다.
다음 흐름으로 정리한다.
- 상속만으로는 다중 계약을 표현하기 어렵다.
- 추상 클래스로 공통 골격과 강제 구현을 분리한다.
- 인터페이스로 역할 계약을 독립적으로 정의한다.
- 두 요소를 조합해 확장성과 결합도 조절을 함께 얻는다.
4. 구성요소·원리·절차
추상 클래스와 인터페이스는 Java에서 추상화(Abstraction)를 구현하는 두 가지 수단이다. 둘 다 객체를 직접 생성할 수 없고, 하위 타입이 구현해야 할 메서드 원형을 정의한다는 점은 같다. 구성 요소와 차이는 아래 표와 같이 정리한다.
| 구분 | 추상 클래스(abstract class) | 인터페이스(interface) |
|---|---|---|
| 선언 키워드 | abstract class | interface |
| 추상 메서드 | abstract 메서드 선언 | 추상 메서드 선언(abstract 생략 가능) |
| 일반 메서드 | 구현 본문 가능 | Java 8 이후 default·static 메서드만 본문 가능 |
| 필드 | 인스턴스 변수 가능 | public static final 상수만 가능 |
| 생성자 | 가짐(자식이 호출) | 가질 수 없음 |
| 상속·구현 관계 | 클래스는 하나의 추상 클래스만 상속 | 클래스는 여러 인터페이스를 implements |
표의 칸 설명 두 가지를 먼저 본다. 추상 클래스는 상태(필드)와 공통 구현을 함께 물려줄 때 쓰고, 인터페이스는 여러 계층에 걸친 행위 계약을 정의할 때 쓴다. 인터페이스의 모든 메서드는 기본적으로 공개(public)이고, 필드는 자동으로 public static final이 된다.
원리는 다형성이다. 참조 변수의 타입을 추상 클래스나 인터페이스로 선언하면, 실제 객체는 구현 클래스의 인스턴스이므로 호출은 구현체의 메서드로 연결된다(동적 바인딩). 이 때문에 클라이언트 코드는 구현체가 바뀌어도 수정하지 않는다.
추상 클래스 선언과 사용 절차는 다음과 같다.
- 공통 속성과 공통 동작을 찾아 추상 클래스로 묶는다.
- 구현이 자식마다 다른 동작은 abstract 메서드로 선언한다.
- 추상 메서드가 하나라도 있으면 클래스에 abstract를 붙인다.
- 자식 클래스는 extends로 상속하고 모든 추상 메서드를 재정의한다.
- 자식 인스턴스를 생성해 추상 타입 참조로 사용한다.
인터페이스 선언과 구현 절차는 다음과 같다.
- 행위를 정의하는 interface를 선언하고, 이름은 XXXable 형태로 짓는다.
- 상수와 추상 메서드 원형만 선언한다.
- 구현 클래스가 implements로 연결하고 모든 메서드를 구현한다.
- 여러 인터페이스는 쉼표로 나열해 implements 한다.
추상 클래스는 is-a 관계의 공통 구현, 인터페이스는 can-do 관계의 행위 계약이다
다음 도식은 두 개념의 구성 관계를 보인다.
5. 관련 법령·기준·표준
이 개념은 법령이 아니라 Java 언어 명세와 개발 표준이 기준이다. 시험에서 외울 기준은 버전과 제약 조건이다. 아래 표는 Java 언어 규칙을 값과 조건으로 정리한 것이다.
| 항목 | 기준 값·조건 | 적용 버전·근거 |
|---|---|---|
| 추상 클래스 인스턴스 생성 | new 연산자로 생성 불가 | Java 언어 명세 |
| 클래스의 상속 개수 | 직접 상속은 1개 | 단일 상속 |
| 인터페이스 구현 개수 | 제한 없음 | 다중 구현 |
| 인터페이스 필드 | public static final 자동 부여 | 상수로만 선언 |
| 인터페이스 default 메서드 | Java 8 이상 | default 키워드 |
| 인터페이스 static 메서드 | Java 8 이상 | 본문 가능 |
| 인터페이스 생성자 | 허용 안 됨 | 인스턴스 상태 불가 |
| 추상 메서드 본문 | 본문 없이 세미콜론 | abstract 메서드 |
개정 연혁은 다음과 같다. Java 8에서 인터페이스에 default와 static 메서드가 도입되어 인터페이스의 구현 제약이 완화됐다. 이 변화 이전에는 인터페이스가 어떤 본문도 가질 수 없었다.
이는 생성자 호출 규칙으로 표에 포함하지 않았다.
6. 유형과 비교
추상 클래스와 인터페이스는 모두 구현을 강제하는 수단이지만 목적과 제약이 다르다. 아래 표는 Java 기준으로 두 개념의 차이를 항목별로 정리한다. 관련 자료와 Java 8 이후 규칙을 함께 반영했다.
| 비교 항목 | 추상 클래스(abstract class) | 인터페이스(interface) |
|---|---|---|
| 선언 키워드 | abstract class | interface |
| 상속·구현 수 | 단일 상속만 가능 | 여러 인터페이스 구현 가능 |
| 인스턴스 변수 | 가질 수 있음 | 상수(public static final)만 가능 |
| 생성자 | 가질 수 있음 | 가질 수 없음 |
| 메소드 구현 | 일반 메소드 본문 가능 | 추상 메소드, default·static 메소드(Java 8 이상) |
| 접근 제한자 | private·protected 멤버 가능 | 구성원은 기본적으로 public |
| 주된 목적 | 공통 상태·기능 공유 | 객체가 따라야 할 계약(규약) 명세 |
이어지는 내용
- 7. 장단점·한계와 개선 방향
- 8. 사례 또는 계산 예제
- 9. 최근 동향과 쟁점
- 10. 흔한 실수와 채점 포인트
- 11. 암기 정리
- 12. 답안 구성 예시
- 13. 예상 변형 문항
로그인하면 하루 2페이지까지 무료로 전체를 읽을 수 있습니다.
앱에서 이 단원 읽기