모든지 기록하자!

[Java] 템플릿(template) 메서드 , final 예약어 (예제 : Player) 본문

Java

[Java] 템플릿(template) 메서드 , final 예약어 (예제 : Player)

홍크 2021. 5. 18. 20:57
728x90

게임 캐릭터에는 레벨이 있다. 레벨이 다르면 그 레벨마다 할 수 있는 역할도 다르다.

이와 같은 상황을 템플릿 메서드로 구현해보자

 

Player가 레벨에 따라 할 수 있는 세 가지 기능이 있다. run(). jump(), turn()이다.

-초보자 레벨 : 천천히 달릴 수(run) 있다.  

-중급자 레벨 : 빠르게 달리고(run) 점프(jump) 할 수 있다.

-고급자 레벨 : 엄청 빠르게 달리고(run) 점프하고(jump) 턴(turn) 할 수 있다. 

Player가 모든 레벨에서 사용할 수 있는 go(int count) 메서드를 제공한다.

go() 메서드는 한 번 run 하고 매개변수로 전달된 count만큼 jump 하고 한번 turn 한다.

그 레벨에서 불가능한 기능을 요청하면 할 수 없다는 메시지를 출력한다.

 

Player 클래스

public class Player {

	private PlayerLevel level; // Player가 가지는 level변수 선언
	
	public Player() { // 디폴트 생성자로 처음 생성되면 BeginnerLever로 시작
		level = new BeginnerLever();
		level.showLeverMessage(); // 해당 레벨 메세지 출력
	}
	
	public PlayerLevel getLevel() {
		return level;
	}
                                // 매개 변수 자료형은 모든 레벨로 변환 가능한 
                                // PlayerLevel로 지정한다.
	public void upgradeLevel(PlayerLevel level) { 
		this.level = level;
		level.showLeverMessage(); // 현재 자신의 level을 매개변수로 받은 level로 변경하고
                                  // 레벨 메세지 출력
	}

	public void play(int count) {
		level.go(count); // PlayerLevel의 템플릿 메서드 go() 호출
	}
	
}

 

PlayerLevel 클래스

public abstract class PlayerLevel {

	public abstract void run();
	public abstract void jump();
	public abstract void turn();
	public abstract void showLeverMessage();
	
	final public void go(int count) { // 재정의 할수 없게 final로 선언
		run();
		for (int i = 0; i < count; i++) {
			jump();
		}
		turn();
	}
}

 

초보 레벨 클래스

public class BeginnerLever extends PlayerLevel {

	@Override
	public void run() {
		System.out.println("천천히 달립니다.");
	}

	@Override
	public void jump() {
		System.out.println("jump 못함");
	}

	@Override
	public void turn() {
		System.out.println("turn 못함");
	}

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

}

 

중급자 레벨 클래스

public class AdvancedLevel extends PlayerLevel{

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

	@Override
	public void jump() {
		System.out.println("높이 jump 합니다.");
	}

	@Override
	public void turn() {
		System.out.println("turn 못함");
	}

	@Override
	public void showLeverMessage() {
		System.out.println("****중급자 레벨입니다.****");
	}

}

 

고급자 레벨 클래스

public class SuperLevel extends PlayerLevel{

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

	@Override
	public void jump() {
		System.out.println("매우 높이 jump 합니다.");
	}

	@Override
	public void turn() {
		System.out.println("한 바퀴 turn!");
	}

	@Override
	public void showLeverMessage() {
		System.out.println("****고급 레벨입니다.****");
	}
}

 

테스트 프로그램

public class MainBoard {

	public static void main(String[] args) {

		Player player = new Player(); // 처음 생성하면 초보자 레벨
		player.play(1);
		
		AdvancedLevel aLevle = new AdvancedLevel();
		player.upgradeLevel(aLevle);
		player.play(2);
		
		SuperLevel sLevle = new SuperLevel();
		player.upgradeLevel(sLevle);
		player.play(3);
	}

}

 

출력 결과

 

추상 클래스와 다형성

모든 레벨 클래스는 PlayerLevel 클래스를 상속받았다. Player가 가질 수 있는 레벨을 별도의 자료형으로 선언하지 않고 PlayerLevel로 선언했다. 레벨을 변경하는 upgradeLevel() 메서드의 매개변수 자료형도

PlayerLevel이다. 따라서 레벨 클래스가 여러 개 존재하더라도 모든 클래스는 PlayerLevel 클래스에 구현된

여러 클래스를 하나의 자료형으로 선언하거나 대입할 수 있다.

final 예약어

final은 '마지막'이란 의미이다. 즉 마지막으로 정한 것이라 더 이상 수정할 수 없다는 뜻이다.

사용위치 설명
변수  final 변수는 상수를 의미한다.
메서드  final 메서드는 하위 클래스에서 재정의할 수 없다.
클래스  final 클래스는 상속할 수 없다.

여러 자바 파일에서 공유하는 상수

public class Define{
	public static final int MIN = 1;
    public static final int MAX = 99999;
    public static final int ENG = 1001;
    public static final int MATH = 2001;
    public static final double PI = 3.14;
    public static final String GOOD_MORNING = "Good Morning!";
}

하나의 자바 파일에서만 사용하는 상수 값은 해당 파일 안에서 정의해서 사용할 수 있다.

여러 파일에서 똑같이 공유해야 하는 상수 값도 있다. 최솟값(MIN) , 최댓값(MAX) 전체에서 공통으로

적용하는 과목 코드 등등 이 있을 것이다. 이런 값을 파일마다 선언하면 코드가 중복되고 값이 변하거나

추가될 때 그 값을 사용하는 파일을 모두 수정해야 한다. 따라서 여러 파일에서 공유해야 하는 상수 값은

한 파일에 모아 public static final로 선언해서 사용하면 좋다.

상속할 수 없는 final 클래스

클래스를 final로 선언하면 상속할 수 없다. 따라서 보안과 관련되어 있거나 기반 클래스가 변하면 안 되는 경우에 클래스를 final로 선언한다. JDK에서 제공하는 클래스 중에 문자열을 나타내는 String이나 

정수 값을 나타내는 Integer 클래스를 예로 들 수 있다.

 

 

728x90
Comments