본문 바로가기
프로그래밍 언어/java

[java] final, 템플릿 메서드

by m2162003 2021. 3. 11.

이전 게시물인 추상 클래스/메서드와 연결되는 주제이다.

 

먼저 final 예약어부터 살펴보자.

 

final 예약어

final 변수는 값이 변경될 수 없는 상수이다. 오직 한번만 값을 할당할 수 있다.

final 메서드 역시 값이 불가능한 메서드로 하위 클래스에서 override(재정의)될 수 없다.

final 클래스의 경우 더 이상 상속되지 않는다. 대표적인 예시로 String 클래스

 

 

public static final 상수값 정의

static을 사용하면 인스턴스를 사용하지 않고 클래스로 직접 참조할 수 있다.

따라서 public static final을 만들면 c의 define과 유사한 역할을 하게 할 수 있다.

고정된 전역변수로 사용가능!

 

 

탬플릿 메서드

추상 케서드나 구현된 메서드를 활용하여 전체의 시나리오를 정의해놓은 메서드

final 예약어를 선언해서 재정의가 불가능하게 만든다.

 

 

템플릿 메서드 패턴

디자인 패턴의 일종

프레임워크에서 많이 사용되는 설계 패턴으로 추상 클래스로 선언된 상위 클래스에서 추상 메서드를 이용하여 전체 구현의 흐름을 정의하고 구체적인 각 메서드 구현은 하위 클래스에 위임한다.

각각의 하위 클래스에 따라 시나리오는 동일하지만 다른 내용이 구현된다.

 

 

예제

package chapter8_templatex;

public abstract class Car {
	public abstract void drive();
	public abstract void stop();
	
	public void startCar() {
		System.out.println("시동걸기");
	}
	
	public void turnOff() {
		System.out.println("시동끄기");
	}
	public void wash() {};
	
    
    //템플릿 메서드
	public final void run() {
		startCar();
		drive();
		stop();
		turnOff();
		wash();
	}
}

run()이라는 템플릿 메서드를 구현했다.

 

AICar와 ManualCar가 Car를 상속받아 run을 구현해보려 한다.

public class AICar extends Car{

	@Override
	public void drive() {
		System.out.println("자율 주행");
		
	}

	@Override
	public void stop() {
		System.out.println("자율주차");
	}
	
	@Override
	public void wash()
	{
		System.out.println("자율 세차");
	}
}


public class ManualCar extends Car{
	
	@Override
	public void drive() {
		System.out.println("수동주행");
	}
	
	@Override
	public void stop() {
		System.out.println("수동 주차");
	}
	
}

public class CarTest {
	public static void main(String[] args) {
		Car ai = new AICar();
		Car manual = new ManualCar();
		
		ai.run();
		System.out.println("======================");
		manual.run();
	}
}

 

 

응용

템플릿 메서드를 사용하여 아주아주아주 간단한 게임을 만들어보자

Player가 게임을 하는데 Player의 레벨에 따라 run(), jump(), turn() 세 가지 기능을 할 수 있다.

레벨에 따라 기능 가능여부가 다르다.

 

Player가 go()명령어를 받으면 세 가지 기능을 모두 수행한다.

 

if 조건문을 걸면 복잡해지고 객체지향이라고 할 수 없다. 객체 지향을 사용하여 코딩해보자.

위와 같은 구성을 그릴 수 있다.

 

레벨을 추상 클래스로 구현 -> 레벨 종류에 따라 레벨을 상속받아 구현

플레이어에 레벨 멤버 변수를 넣기

 

레벨 추상 클래스

public abstract class PlayerLevel {
	public abstract void run();
	public abstract void jump();
	public abstract void turn();
	public abstract void showLevel();
	public final void go(int cnt) {
		run();
		for(int i=0; i<cnt; i++) {
			jump();
		}
		turn();
		showLevel();
	};
}

 

각 레벨 구현

public class Beginner extends PlayerLevel {
	@Override
	public void run() {
		System.out.println("천천히 달리기");
	}
	@Override
	public void jump() {
		System.out.println("점프 불가능");
	}

	@Override
	public void turn() {
		System.out.println("회전 불가능");
	}

	@Override
	public void showLevel() {
		System.out.println("***초보자입니다.****");
	}

}

public class Advanced extends PlayerLevel{

	@Override
	public void run() {
		System.out.println("빨리 달리기");
		
	}

	@Override
	public void jump() {
		System.out.println("점프 낮게 가능");
	}

	@Override
	public void turn() {
		System.out.println("회전 불가능");
	}

	@Override
	public void showLevel() {
		System.out.println("***중수입니다.****");
	}
}

package chapter8_gamelvel;

public class Super extends PlayerLevel{

	@Override
	public void run() {
		System.out.println("매우 빨리 달리기");	
	}

	@Override
	public void jump() {
		System.out.println("점프 높게 가능");
	}

	@Override
	public void turn() {
		System.out.println("회전 가능");
	}

	@Override
	public void showLevel() {
		System.out.println("***고수입니다.****");
	}

}


 

 

플레이어 객체 구현

public class Player {
	private PlayerLevel level;
	
	public Player() {
		level = new Beginner(); //생성자에서 level 객체를 생성한다.
		level.showLevel();
	}

	public PlayerLevel getLevel() {
		return level;
	}
	
	public void upgradeLevel(PlayerLevel level) {
		this.level = level;
		level.showLevel();
	}
	
	void play(int cnt) {
		level.go(cnt);
	}

}

 

메인에서 실행

public class LevelTest {
	public static void main(String[] args) {
		Player player = new Player();
		player.play(1);

		Advanced adv = new Advanced();
		player.upgradeLevel(adv);

		player.play(2);

		Super sup = new Super();
		player.upgradeLevel(sup);

		player.play(3);
	}
}

 

완성!

'프로그래밍 언어 > java' 카테고리의 다른 글

[java] 인터페이스 다중 상속  (0) 2021.03.12
[java] 인터페이스  (0) 2021.03.12
[java] 추상클래스  (0) 2021.03.11
[java] 업캐스팅, 타운캐스팅  (0) 2021.03.10
[java] 상속, 생성과정  (0) 2021.03.09

댓글