추상 클래스 vs 인터페이스
Coddy Java 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 87개 중 38번째.
이제 both abstract classes와 인터페이스를 모두 이해했으므로, 언제 한쪽을 다른 쪽보다 사용해야 하는지에 대한 일반적인 질문이 생깁니다. 선택은 무엇을 모델링하려고 하는지에 따라 달라집니다.
클래스들이 공유 상태 또는 behavior를 가진 공통 기반을 공유할 때는 abstract class를 사용하세요. abstract class에는 인스턴스 변수, constructor, 그리고 abstract 메서드와 concrete 메서드를 혼합하여 포함할 수 있습니다.
public abstract class Animal {
protected String name; // 공유 상태
public Animal(String name) {
this.name = name;
}
public void sleep() { // 공유 동작
System.out.println(name + " is sleeping");
}
public abstract void makeSound(); // 반드시 구현되어야 함
}서로 관련 없는 클래스가 공유할 수 있는 interface를 정의하려면 interface를 사용하세요. 인터페이스는 객체가 무엇인지가 아니라 무엇을 할 수 있는지에 초점을 둡니다:
public interface Flyable {
void fly();
}
// 관련 없는 클래스들이 이 기능을 공유할 수 있습니다
class Bird extends Animal implements Flyable { ... }
class Airplane implements Flyable { ... }
class Drone implements Flyable { ... }간단히 비교해 보겠습니다:
| 기능 | Abstract 클래스 | 인터페이스 |
|---|---|---|
| 인스턴스 변수 | 예 | 상수만 |
| 생성자 | 예 | 아니요 |
| 다중 상속 | 아니요 (단일 extends) | 예 (다중 implements) |
| 접근 제어자 | 모두 가능 | public만 (abstract 메서드의 경우) |
실용적인 지침: abstract 메서드만 있고 상태가 없는 abstract 클래스를 만들고 있다면, 인터페이스가 더 나은 선택일 가능성이 큽니다.
챌린지
쉬움abstract classes와 인터페이스를 언제 사용해야 하는지 보여 주는 vehicle system을 만들어 보겠습니다. abstract class를 통해 공통 state와 behavior를 공유하는 vehicles를 모델링하고, 인터페이스를 통해 선택적 capability를 추가합니다.
코드를 다섯 개의 파일로 구성합니다.
Vehicle.java: 모든 vehicles의 기반 역할을 하는 abstract class를 Create합니다. 모든 vehicle에는brandfield (String)와yearfield (int)가 있습니다. 두 fields를 초기화하는 constructor, 각 field에 대한 getter methods, 그리고 String을 반환하는 abstract methodstartEngine()를 포함합니다. 또한 다음을 반환하는 concrete methodgetInfo()도 추가합니다:[brand] ([year]). 이는 abstract class를 사용하기에 완벽한 경우입니다. vehicles는 state (brand, year)와 일부 behavior (getInfo)를 공유하지만, 각 vehicle은 서로 다른 방식으로 engine을 시작하기 때문입니다.Convertible.java: roof를 convert할 수 있는 vehicles를 위한 인터페이스를 Declare합니다. 이 capability는 vehicle이 무엇인지(is)에 연결된 것이 아니라, 특정 vehicles가 할 수 있는 일(can do)입니다. 두 methods인openRoof()와closeRoof()를 Declare하며, both String을 반환합니다.Car.java:Vehicle을 extends하고Convertible을 implements하는 class를 Create합니다. Car에는 추가로numDoorsfield (int)가 있습니다. 상속받은 fields를 초기화하려면super를 사용합니다.startEngine()을 구현하여 다음을 반환합니다:[brand] car engine started.openRoof()을 구현하여 다음을 반환하고:[brand] roof opening,closeRoof()을 구현하여 다음을 반환합니다:[brand] roof closing.Motorcycle.java:Vehicle을 extends하지만Convertible을 implements하지 않는 class를 Create합니다. motorcycles에는 roof가 없습니다! Motorcycle에는hasSidecarfield (boolean)가 있습니다.startEngine()을 구현하여 다음을 반환합니다:[brand] motorcycle engine roaring.Main.java: abstract classes와 인터페이스의 차이를 보여 주도록 모든 것을 결합합니다. 네 가지 입력을 받습니다: car brand, car year, motorcycle brand, motorcycle year.Car (4개의 doors)와 Motorcycle (sidecar 없음)을 Create합니다. 먼저 두 vehicles에 대해
getInfo()를 출력하여 공유되는 abstract class behavior를 보여 줍니다. 두 vehicles 모두 이를 Vehicle에서 상속받습니다. 그런 다음 각 vehicle의startEngine()결과를 출력합니다. 각 vehicle type이 이를 서로 다르게 구현한다는 점에 주목하세요.마지막으로 인터페이스 capability를 보여 줍니다. Car만
Convertible을 implements하므로, car에 대해서만openRoof()을 호출하고 출력한 다음closeRoof()를 호출하고 출력합니다.
네 가지 입력을 받습니다: car brand (String), car year (int), motorcycle brand (String), motorcycle year (int).
출력은 총 여섯 줄이어야 합니다. 두 vehicles가 abstract class의 state와 getInfo() method를 공유하지만, Car만 convertible capability를 가진다는 점에 주목하세요. 이는 각 접근 방식을 언제 사용해야 하는지 보여 줍니다!
직접 해보기
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 입력 읽기
String carBrand = scanner.nextLine();
int carYear = scanner.nextInt();
scanner.nextLine(); // 개행 소비
String motorcycleBrand = scanner.nextLine();
int motorcycleYear = scanner.nextInt();
// TODO: 문이 4개인 Car 생성
// TODO: 사이드카 없는 Motorcycle 생성 (false)
// TODO: 두 차량 모두에 대해 getInfo() 출력 (공유 추상 클래스 동작 시연)
// TODO: 두 차량 모두에 대해 startEngine() 출력 (서로 다른 구현 시연)
// TODO: 자동차에만 openRoof()와 closeRoof() 출력 (인터페이스 기능 시연)
}
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
4상속
상속의 기초 (extends)super 키워드메서드 오버라이딩 (@Override)생성자 체이닝Object 클래스단일 및 다중 레벨 상속다중 클래스 상속이 불가능한 이유요약 - 직원 계층 구조6인터페이스와 추상 클래스
인터페이스 소개인터페이스 구현하기다중 인터페이스 구현인터페이스의 Default 및 Static 메서드추상 클래스 vs 인터페이스함수형 인터페이스복습 - 결제 시스템직접 연습해 보세요: 온라인 Java 컴파일러