09-1. 추상 클래스
추상 클래스란?
- 구현 코드 {} 없이 메서드의 선언만 있는 추상 메서드(abstract method)를 포함한 클래스
- 메서드 선언(declaration) : 변환타입, 메서드 이름, 매개변수로 구성
- 메서드 정의(definition) : 메서드 구현(implementation)과 동일한 의미 구현부(body)를 가짐 {}
int add (int x, int y); // 선언 → { } 구현부 없음 → 추상 메서드 → abstract 예약어 사용 int add (int x, int y) { } // { } 구현부가 있음 → 추상 메서드 X |
- abstract 예약어를 사용
- 추상 클래스는 new 할 수 없음 (인스턴스화 할 수 없음)
추상 클래스 구현하기
- 메서드에 구현 코드가 없으면 abstract로 선언
- abstract로 선언된 메서드를 가진 클래스는 abstract 로 선언
- 모든 메서드가 구현 된 클래스라도 abstract로 선언되면 추상 클래스로 인스턴스화 할 수 없음
- 추상 클래스의 추상 메서드는 하위 클래스가 상속 하여 구현
- 추상 클래스 내의 추상 메서드 : 하위 클래스가 구현해야 하는 메서드
- 추상 클래스 내의 구현 된 메서드 : 하위 클래스가 공통으로 사용하는 메서드 (필요에 따라 하위 클래스에서 재정의 함)
09-2. 템플릿 메서드
- 추상 메서드나 구현 된 메서드를 활용하여 코드의 흐름(시나리오)를 정의하는 메서드
- final로 선언하여 하위 클래스에서 재정의 할 수 없게 함
- 프레임워크에서 많이 사용되는 설계 패턴
- 추상 클래스로 선언된 상위 클래스에서 템플릿 메서드를 활용하여 전체적인 흐름을 정의하고 하위 클래스에서 다르게 구현되어야 하는 부분은 추상 메서드로 선언하여 하위 클래스에서 구현 하도록 함
Car.java
![]() |
AIcar.java
![]() |
ManualCar
![]() |
CarTest
![]() |
09-3. 템플릿 메서드 응용하기
예제 시나리오
Player가 있고, 이 Player가 게임을 합니다. 게임에서 Player가 가지는 레벨에 따라 할 수 있는 세 가지 기능이 있습니다. 바로 run(), jump(), turn() 입니다. ● 초보자 레벨 : 천천히 달릴(run) 수 있습니다. ● 중급자 레벨 : 빠르게 달리고(run) 점프할(jump) 수 있습니다. ● 고급자 레벨 : 엄청 빠르게 달리고(run) 점프하고(jump) 턴할(turn) 수 있습니다. 모든 레벨에서 Player가 사용할 수 있는 필살기인 go(int count) 메서드를 제공합니다. go() 메서드는 한 번 run하고, 매개변수로 전달된 count만큼 jump하고, 한 번 turn 합니다. 그 레벨에서 불가능한 기능을 요청하면 할 수 없다는 메시지를 출력합니다. |
클래스 설계
player 레벨에 따라 if 조건문으로 코드를 구현할 수도 있으나 level 수 만큼 if문이 증가해서 코드가 복잡해질 것이다. 만약 level이 10개 정도라면 각 level마다 if-else if문을 10개씩 코딩해야하니 비효율적이다. 그러므로 각 플레이어가 가질 수 있는 레벨을 클래스로 분리하고 상속관계로 표현해보자. 각 레벨마다 공통 기능을 추상클래스 (PlayerLevel) 에서 구현하고 각 레벨마다 달라지는 기능은 추상 메서드로 구현해보자. |
Player.java
package gamelevel;
public class Player { private PlayerLevel level; //Player가 가지는 level 변수 선언 public Player() { //디폴트 생성자 level = new BeginnerLevel(); //처음 생성되면 비기너레벨로 시작 level.showLevelMessage(); // 레벨 메세지 출력 } public PlayerLevel getLevel() { return level; } public void upgradeLevel(PlayerLevel level) { //매개변수 자료형은 모든 레벨로 변환 가능한 PlayerLevel this.level = level; //현재 자신의 level을 매개변수로 받은 level로 변경하고 level.showLevelMessage(); //레벨 메세지 출력 } public void play(int count) { level.go(count); //PlayerLevel의 템플릿 메서드 go() 호출 } } |
PlayerLevel.java
package gamelevel;
public abstract class PlayerLevel { public abstract void run(); public abstract void jump(); public abstract void turn(); public abstract void showLevelMessage(); final public void go(int count) { //모든 레벨에서 동일하고 재정의되면 안되므로 final로 선언 run(); for(int i = 0; i < count; i++) { jump(); } turn(); } } |
BeginnerLevel.java
package gamelevel;
public class BeginnerLevel 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 showLevelMessage() { System.out.println("***** 초보자 레벨입니다. *****"); } } |
AdvancedLevel.java
package gamelevel;
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 showLevelMessage() { System.out.println("***** 중급자 레벨입니다. *****"); } } |
SuperLevel.java
package gamelevel;
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("한 바퀴 돕니다."); } @Override public void showLevelMessage() { System.out.println("***** 고급자 레벨입니다. *****"); } } |
MainBoard.java
package gamelevel;
public class MainBoard { public static void main(String[] args) { Player player = new Player(); //처음 생성하면 BeginnerLevel player.play(1); //play() 메서드의 매개변수에 1을 입력하면 초보자 레벨 AdvancedLevel aLevel = new AdvancedLevel(); //중급자 클래스 생성 player.upgradeLevel(aLevel); //aLevel 참조 변수를 upgradeLevel()메서드에 대입해서 레벨을 업그레이드 player.play(2); //play() 메서드의 매개변수에 값을 대입하면 빨리 달린 후 매개변수로 입력된 값만큼 jump SuperLevel sLevel = new SuperLevel(); player.upgradeLevel(sLevel); player.play(3); } } |
09-4. final 예약어
- final 변수 : 값이 변경될 수 없는 상수
public static final double PI = 3.14; |
- final 메서드 : 하위 클래스에서 재정의 할 수 없는 메서드
- final 클래스 : 상속할 수 없는 클래스
- 보안과 관련되어 있거나 기반 클래스가 변하면 안 되는 경우에는 클래스를 final로 선언
'Programming Language > JAVA' 카테고리의 다른 글
인터페이스(interface) (0) | 2023.05.25 |
---|---|
[Do it 자바 프로그래밍 입문] 10.인터페이스 (0) | 2023.05.25 |
[Do it 자바 프로그래밍 입문] 08.상속과 다형성 (1) | 2023.05.23 |
아리송한 개념들 짜집기 모음 (0) | 2023.05.22 |
[Do it 자바 프로그래밍 입문] 객체지향 입문 복습 문제 풀이 (0) | 2023.05.22 |