728x90
추상 클래스와 템플릿 메서드 (무슨 관계일까?)
- 추상 클래스를 활용한 예가 바로 템플릿 메서드입니다.
- '템플릿 template' 이란 용어는 무엇을 뜻할까요?
- 사전에서 보면 틀이나 견본을 뜻합니다.
- 틀이 있는 메서드라는 의미지요.
- 템플릿 메서드는 05장에서 소개한 싱글톤 패턴과 같은 디자인 패턴입니다. (이전 포스팅 참조)
- 즉 템플릿 메서드는 디자인 패턴의 한 방법으로 모든 객체 지향 프로그램에서 사용하는 구현 방법입니다.
- 따라서 이 구현 방법은 자바뿐 아니라 C++, C# 에서도 동일하게 적용됩니다.
- 예시를 통해서 알아보겠습니다.
public abstract class Car {
public abstract void drive();
public abstract void stop();
public void startCar() {
System.out.println("시동을 켭니다.");
}
public void turnOff() {
System.out.println("시동을 끕니다.");
}
final public void run() {
startCar();
drive();
stop();
turnOff();
}
}
- Car 클래스를 생성했습니다.
- 이 클래스는 drive( ), stop( ) 2개의 추상 메서드와 3개의 구현된 메서드를 가지고 있습니다.
- 시동을 끄고 켜는 것은 어떤 차이던 간에 모두 같기 때문에 일반 메서드로 구현을 했습니다.
- 반대로 주행과 멈추는 기능은 차종에 따라 다를 수 있기 때문에 추상 메서드로 구현을 했습니다.
- 제일 아래에 있는 run( ) 메서드를 확인해보겠습니다.
- run( ) 메서드는 시동을 켜고, 달리고, 멈추고, 시동을 끄는 모든 메서드를 사용합니다.
- 만약 Car 클래스를 상속받으면 어떤 자동차든 모두 이 순서대로 동일한 방식으로 달리는 것입니다.

- Car 클래스를 상속 받을 클래스를 2개 구현해 보겠습니다.
- 자율 주행 자동차와 일반 자동차 클래스들은 추상 클래스 Car 를 상속받았기 때문에 구현되지 않은 추상 메서드를 마저 구현해야 합니다.
- AI 클래스와 Manual 클래스를 구현해보도록 하겠습니다.
public class AICar extends Car {
@Override
public void drive() {
System.out.println("자율 주행합니다");
System.out.println("자동차가 알아서 방향을 전환합니다");
}
@Override
public void stop() {
System.out.println("스스로 멈춥니다");
}
}
public class ManualCar extends Car{
@Override
public void drive() {
System.out.println("사람이 운전합니다");
System.out.println("사람이 핸들을 조작합니다");
}
@Override
public void stop() {
System.out.println("브레이크로 정지합니다");
}
}
- 두 클래스 모두 상속받은 추상 메서드를 구현했습니다.
- 이제 테스트 프로그램을 만들어서 두 자동차의 동작을 확인해보겠습니다.
public class CarTest {
public static void main(String[] args) {
System.out.println("=== 자율 주행하는 자동차 ===");
Car myCar = new AICar();
myCar.run();
System.out.println("=== 사람이 운전하는 자동차 ===");
Car hisCar = new ManualCar();
hisCar.run();
}
}

템플릿 메서드의 역할 (final 예약어)
- CarTest 에서 두 개의 인스턴스를 생성했었습니다.
- 그리구 run( ) 메서드를 호출했습니다.
- run( ) 메서드는 Car 클래스에서 이미 구현된 메서드입니다.
- 차가 달리고 멈추는 과정은 어느 차이건 모두 동일합니다. 다만 상세한 방법들이 다를 뿐이죠.
- 이렇게 템플릿 메서드의 역할을 메서드 실행 순서와 시나리오를 정의하는 것입니다.
- 템플릿 메서드 안에는 추상 메서드와 일반 메서드 모두 올 수 있습니다.
- 템플릿 메서드에서 호출하는 메서드가 추상 메서드라면 차종에 따라 구현 내용이 바뀔 수 있습니다.
- 우리가 보았던 예제에서 바뀌었던 것과 마찬가지로 말이죠.
- 하지만 시동을 켜고, 달리고, 멈추고, 시동을 끄는 시나리오 자체는 변하지 않습니다.
- 이런 메서드를 템플릿 메서드로 정의하는 것입니다.
- 템플릿 메서드는 실행 순서, 즉 시나리오를 정의한 메서드이므로 바뀔 수 없습니다.
- 상위 클래스를 상속받은 하위 클래스에서 템플릿 메서드를 재정의하면 안 된다는 것입니다.
- 그래서 템플릿 메서드는 final 예약어를 사용해 선언합니다.
- 메서드 앞에 final 을 사용하면 상속받은 하위 클래스가 메서드를 재정의할 수 없습니다.
- 템플릿 메서드는 로직 흐름이 이미 정해져 있는 프레임워크에서 많이 사용하는 기본 구현 방법입니다.
템플릿 메서드와 final 예약어 정리하자면!
- 추상 클래스는 하위 클래스에서도 사용할 수 있는 코드를 구현합니다.
- 그런데 일반 메서드는 하위 클래스에서 재정의할 수 있습니다.
- 즉 start( ) 와 turnOff( ) 도 추가 기능이 필요하다면 하위 클래스에서 재정의해서 사용하면 됩니다.
- 하지만 템플릿 메서드는 로직 흐름을 정의하는 역할을 수행합니다.
- 즉 템플릿 메서드는 하위 클래스에서 재정의를 통해서 수정이 되어서는 안되는 메서드이다.
- 따라서 하위 클래스에서 수정을 할 수 없게 만드는 예약어 final 을 함께 사용하여 템플릿 메서드를 선언합니다.
final 좀 더 알아보기

- final 예약어는 쓰이는 위치에 따라 수행하는 역할이 달라집니다.
- 변수 앞에 사용하면 값을 변경할 수 없게 됩니다. 변수가 상수가 됩니다.
- 메서드 앞에 사용하면 재정의할 수 없는 메서드가 됩니다.
- 클래스 앞에 사용하면 상속될 수 없는 클래스가 됩니다.
'[그린컴퓨터] Server > JAVA(객체 지향 프로그래밍)' 카테고리의 다른 글
| final 예약어 { 상수를 의미하는 final 변수, 상속할 수 없는 final 클래스, TDD } (0) | 2023.06.01 |
|---|---|
| 템플릿 메서드 응용하기 { 예제 이해하기, 클래스 기능과 관계, 클래스 설계하기, 추상 클래스와 다형성 } (0) | 2023.06.01 |
| 추상 클래스 { 추상 클래스란, 추상 클래스 구현하기, 추상 클래스를 만드는 이유 } (0) | 2023.05.31 |
| 다운 캐스팅과 instanceof { 다운 캐스팅이란, instanceof란 } (0) | 2023.05.31 |
| 다형성 활용하기 { 배열과 다형성, 배열과 다형성 활용하기, 상속은 언제 사용할까 } (0) | 2023.05.31 |