[Java] 추상 클래스 - 추상클래스의 응용 템플릿 메서드

나영원·2020년 8월 30일
0

Java_basic

목록 보기
46/60

템플릿 메서드

  • 틀이나 견본을 의미하는 템플릿을 붙인 템플린 메서드는 추상 메서드나 구현된 메서드를 활용하여 전체의 흐름(시나리오)를 정의 해놓은 메서드를 뜻합니다. final로 선언하여 하위 클래스에서 재정의 될 수 없게 하고 그렇기에 전체의 흐름이 정의되있다고 얘기할 수 있는 것입니다.

  • 템플릿 메서드는 Java에서만 사용되는 개념이아닌 디자인 패턴의 일종으로 프레임워크에서 많이 사용되는 페턴입니다. 추상 클래스로 선언된 상위클래스에서 추상메서드를 이용하여 전체적인 흐름을 정의하고 하위 클래스에서 각 메서드에 대한 구체적인 구현을 하도록 위임하는 방식입니다.

템플릿 메서드 구현하기 예제

  • 왼쪽 클래스 관계도에서 볼수 있듯이 Car라는 상위 클래스를 추상클래스로 정의하여 차의 공동적인 기능들인 startCar(), tunOff(), run()을 이미 구현해 놓았고 그외에 하위 클래스인 AICar와 ManualCar에서 개별적으로 구현해야 할 drive(), stop() 메서드를 추상메서드로 두었습니다.

  • 메서들 중에 run()메서드는 전체적으로 차의 움직임에 흐름을 조직하는 기능을 하는 메서드로 각 메서드들의 활용하는 순서가 정의되어 있고 이런 기능을 하는 메서드를 템플릿 메서드라고 합니다.

  • startCar();나 turnOff()같이 상위클래스에서 구현된 메서드들도 하위클래스에서 재정의 될 수 있습니다.

public abstract class Car {
	//1번
	public abstract void drive();
	public abstract void stop();
	//2번
	public void startCar() {
		System.out.println("시동을 켭니다.");
	}
	public void turnoff() {
	System.out.println("시동을 끕니다.");
	}
	//3번
	final public void run() {
		startCar();
		drive();
		stop();
		turnoff();
	} //템플릿메서드
}
  • 1번 : Car클래스를 생성하고 추상메서드인 drive()와 stop()을 작성하고 abstract를 각메서드와 클래스의 선언해줍니다.

  • 2번 : 상위 클래스에서 구현되어야할 stratCar()와 turnOff() 클래스를 작성합니다.

  • 3번 : 메서드들의 전체적인 흐름을 조직하는 run() 메서드를 작성하고 각 메서드들을 순서에 맞게 입력합니다. 이렇게 전체적인 흐름을 구성하는 메서드들 템플릿 메서드라고 하고 하위 클래스에서 재정의 할 수 없게 앞에 final을 붙여 줍니다.

public class AICar extends Car {

	@Override
	public void drive() {
		System.out.println("자율 주행합니다");
		System.out.println("자동차가 스스로 방향을 바꿉니다.");
	}

	@Override
	public void stop() {

		System.out.println("스스로 멈춥니다");
	}
}

AICar 클래스를 만들고 하위클래스에서 구체화 되어야 할 drive()와 stop()을 작성합니다.

public class MannualCar extends Car {
	@Override
	public void drive() {
		System.out.println("사람이 운전합니다.");
		System.out.println("사람이 핸들을 조작합니다.");
	}
	@Override
	public void stop() {
		System.out.println("브레이크를 밟아서 정지합니다.");
	}
}

MannualCar 클래스를 작성하고 drive()와 stop()을 작성합니다.

public class CarTest {

	public static void main(String[] args) {

		Car aiCar = new AICar();
		aiCar.run();
		System.out.println("=======================");
		Car mannualCar = new MannualCar();
		mannualCar .run();
	}
}
///결과
시동을 켭니다.
자율 주행합니다
자동차가 스스로 방향을 바꿉니다.
스스로 멈춥니다
시동을 끕니다.
=======================
시동을 켭니다.
사람이 운전합니다.
사람이 핸들을 조작합니다.
브레이크를 밟아서 정지합니다.
시동을 끕니다.
  • CarTest클래스를 만들고 AICar와 MannalCar 인스턴스를 상위클래스인 Car를 타입으로 하여 생성하고 run()메서드를 각각 사용하면 아래와 같은 결과물이 출력됩니다.

  • 이처럼 전체적인 흐름을 정해져 있지만 각 하위 클래스에 따라 달라져야 할 구체적인 내용을 추상메서드로 작성하여 구성하는 것을 템플릿 메서드라고 합니다.

훅메서드

	//1번
	public void washCar() {};
	//2번
	final public void run() {
		startCar();
		drive();
		stop();
		turnoff();
		washCar();
		
	}
  • 1번의 washCar()와 같이 구현부가 있지만 내용이 비어있는 메서드를 훅 메서드라고 합니다. 추상 메서드와는 다르게 에러가 나지 않고 하위 클래스에서 재정의 하지 않더라도 에러가 나지 않습니다.

  • 이런 훅메서드는 하위클래스에서 선택적인 오버라이딩을 할때 사용됩니다. 2번과 같이 washCar();을 run에 포함시키더라도 CarTest에 실행 결과에는 변한이 없습니다.

//AICar 클래스
	@Override
	public void washCar() {
		System.out.println("자동 세차 합니다.");
	}
    
    
시동을 켭니다.
자율 주행합니다
자동차가 스스로 방향을 바꿉니다.
스스로 멈춥니다
시동을 끕니다.
자동 세차 합니다.
  • AICar 클래스에 washCar 메서드를 재정의하고 CarTest 클래스에서 출력을 해보면 자동세차합니다가 추가된것을 알 수 있습니다.

  • 이렇듯 훅메서드는 추상메서드와 같이 상위 클래스에서 정의되고 하위클래스에서 구현하는 역할을 하지만 훅메서드는 재정의를 하지 않아도 오류가 발생하거나 abstract를 선언해줄 필요가 없습니다.

final 예약어

  • final 변수는 값이 변할 수 없는 상수입니다. static과 함께 변하지 않는 값을 사용하고 싶을 때 많이 활용됩니다.
  • firnal 메서드는 하위 클래스에서 재정의(overriding)할 수 없습니다. 또한 final 클래스는 상속 할 수 없습니다.

public static final 상수 값 정의 하여 사용하기

  • 프로젝트 구현시 시 여러 파일에서 공유해야 하는 상수 값은 하나의 클래스에 선언하여 사용하면 편리합니다.

  • 위의 예시 처럼 Define 이란 클래스에 public static final 을 선언하고 상수값을 입력하면 다른 클래스들에서 생성자를 생하지 않고 클래스명.상수명(Define.MIN,MAX..등)을 통해서 언제든지 상수를 불러와서 사용할 수 있게됩니다.

profile
배우는 개발 일기

0개의 댓글