추상 클래스와 메서드
Coddy Java 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 87개 중 32번째.
때로는 청사진 역할을 하지만 직접 인스턴스화해서는 안 되는 클래스를 정의하고 싶을 때가 있습니다. 예를 들어, 일반적인 Shape 클래스는 부모 클래스로서 의미가 있지만, 구체적인 형태가 없는 "도형"은 어떤 모습일까요? 바로 이럴 때 추상 클래스(abstract classes)가 사용됩니다.
추상 클래스는 abstract 키워드로 선언되며 인스턴스화할 수 없습니다. 여기에는 구현부가 있는 일반 메서드와 본문이 없는 추상 메서드가 모두 포함될 수 있습니다:
public abstract class Shape {
protected String color;
public Shape(String color) {
this.color = color;
}
// 추상 메서드 - 구현부가 없음
public abstract double getArea();
// 일반 메서드 - 구현부가 있음
public String getColor() {
return color;
}
}추상 메서드는 서브클래스가 무엇을 해야 하는지를 선언하지만, 어떻게 해야 하는지는 선언하지 않습니다. 추상 클래스를 상속받는 모든 일반 클래스는 모든 추상 메서드에 대한 구현을 제공해야 합니다:
public class Circle extends Shape {
private double radius;
public Circle(String color, double radius) {
super(color);
this.radius = radius;
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
}추상 클래스를 참조 타입으로 계속 사용할 수 있어 다형성을 구현할 수 있습니다:
Shape shape = new Circle("red", 5.0);
System.out.println(shape.getArea()); // Circle의 구현을 호출합니다추상 클래스는 서브클래스들이 공통 코드를 공유하면서도 각자 특정 동작을 다르게 구현해야 할 때 이상적입니다. 이는 코드 재사용을 허용하면서도 계약을 강제합니다.
챌린지
쉬움추상 클래스의 강력함을 보여주는 가전제품 시스템을 구축해 보겠습니다. 모든 가전제품이 수행해야 할 작업을 정의하는 기본 Appliance 클래스를 만들고, 특정 가전제품 유형이 그 작업을 정확히 어떻게 수행할지 결정하도록 할 것입니다.
코드는 다음 네 개의 파일로 구성됩니다:
Appliance.java: 모든 가전제품의 청사진 역할을 하는 추상 클래스를 생성합니다. 모든 가전제품은brand필드(String)와wattage필드(int)를 가집니다. 두 필드를 초기화하는 생성자, 각 필드에 대한 getter 메서드, 그리고[brand] - [wattage]W를 반환하는 일반 메서드getInfo()를 포함하세요. 하위 클래스가 반드시 구현해야 하는 추상 메서드operate()를 정의하세요. 이는 각 가전제품이 주요 기능을 수행하는 방식을 나타냅니다.WashingMachine.java: Appliance를 상속받는 구체 클래스를 생성합니다. 세탁기는 kg 단위의 세탁 용량을 나타내는capacity필드(int)를 추가로 가집니다. 부모 클래스의 초기화를 처리하기 위해super를 사용하세요.operate()메서드를 구현하여[brand] washing machine is washing [capacity]kg of clothes를 출력하도록 하세요.Microwave.java: Appliance를 상속받는 또 다른 구체 클래스를 생성합니다. 전자레인지는 전력 수준 백분율을 나타내는power필드(int)를 가집니다.operate()를 구현하여[brand] microwave is heating at [power]% power를 출력하도록 하세요.Main.java: 다형성을 사용하여 모든 것을 하나로 묶습니다. 브랜드 이름, 소비 전력, 세탁기 용량, 또 다른 브랜드 이름, 전자레인지 전력 수준 등 다섯 개의 입력을 받습니다. WashingMachine과 Microwave를 생성한 다음, 이를Appliance참조 배열에 저장합니다. 배열을 루프하며 각 가전제품에 대해getInfo()를 사용하여 정보를 출력한 다음operate()를 호출하세요.
입력은 첫 번째 브랜드(String), 첫 번째 소비 전력(int), 세탁 용량(int), 두 번째 브랜드(String), 전력 수준(int) 순서로 다섯 개가 주어집니다.
출력은 네 줄로 표시되어야 합니다. 각 가전제품에 대해 정보 줄과 작동 동작이 차례로 나타납니다. 추상 클래스를 통해 서로 다른 가전제품을 통일된 방식으로 다루면서도 각 가전제품이 고유한 방식으로 작동하는 것을 확인해 보세요!
치트 시트
추상 클래스는 abstract 키워드로 선언되며 직접 인스턴스화할 수 없습니다. 이는 서브클래스를 위한 설계도 역할을 합니다:
public abstract class Shape {
protected String color;
public Shape(String color) {
this.color = color;
}
// 추상 메서드 - 구현부가 없음
public abstract double getArea();
// 일반 메서드 - 구현부가 있음
public String getColor() {
return color;
}
}추상 메서드는 본문이 없으며 추상이 아닌 서브클래스에서 반드시 구현해야 합니다:
public class Circle extends Shape {
private double radius;
public Circle(String color, double radius) {
super(color);
this.radius = radius;
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
}추상 클래스는 다형성을 위한 참조 타입으로 사용될 수 있습니다:
Shape shape = new Circle("red", 5.0);
System.out.println(shape.getArea()); // Circle의 구현체를 호출함추상 클래스는 서브클래스들이 공통 코드를 공유하지만 특정 동작은 다르게 구현해야 할 때 이상적입니다.
직접 해보기
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 입력 읽기
String brand1 = scanner.nextLine();
int wattage1 = scanner.nextInt();
int capacity = scanner.nextInt();
scanner.nextLine(); // 개행 문자 처리
String brand2 = scanner.nextLine();
int power = scanner.nextInt();
// TODO: brand1, wattage1, capacity를 사용하여 WashingMachine 객체 생성
// TODO: brand2, wattage1 (또는 적절한 wattage), power를 사용하여 Microwave 객체 생성
// TODO: Appliance 참조 배열을 생성하고 두 객체를 저장
// TODO: 배열을 순회하며 각 가전제품(appliance)에 대해:
// - getInfo()를 사용하여 정보 출력
// - operate() 호출
}
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
4상속
상속의 기초 (extends)super 키워드메서드 오버라이딩 (@Override)생성자 체이닝Object 클래스단일 및 다중 레벨 상속다중 클래스 상속이 불가능한 이유요약 - 직원 계층 구조