백엔드 개발자 2024. 7. 6. 12:39

 

 

목적

앞으로 예제시 사용하기 위해, 지금 껏 배워온 객체지향의 개념을 담기 위해

 

클래스 설명


 

public enum Side {
    RED("레드"), BLUE("블루");
    private String name;

    Side(String name) { this.name = name; }

    public String getName() { return name; }
}

 

  • 게임 진영 구분을 열거형 enum을 사용해서 나타낸 예제

 

 

추상 클래스 활용

	public abstract class Unit {
    
		//  ⚠️ 이후 실습의 편의를 위해 일부 필드를 public으로
    //  - 실무에서는 private로 만들고 getter/setter 권장
    public Side side;
    public int hp;

    public Unit(Side side, int hp) {
        this.side = side;
        this.hp = hp;
    }

		public Side getSide() {
        return side;
    }
}

 

  • 이 클래스만으로 모든 유닛이 정해지는게 아니므로 가져다 사용할 수 있도록 추상클래스 
  • 실습 편의를 위해 public으로 필드를 사용했다.

 

 

public interface Attacker {
    void defaultAttack(Unit target);
}

 

  • 인터페이스로 생성

 

 

 

검사 클래스

public class Swordman extends Unit implements Attacker {
    public Swordman(Side side) {
        super(side, 80);
    }

    private void swordAttack(Unit target) {
        target.hp -= 10;
    }

    @Override
    public void defaultAttack(Unit target) {
        swordAttack(target);
    }

		@Override
    public String toString() {
        return side.toString() + " 진영 검사";
    }
}

 

  • Unit 클래스를 상속받고 Attacker를 구현하는 클래스
  • 생성자로 사이드를 받아와서 Unit 생성자를 실행한다.

 

 

 

 

기사 클래스

public class Knight extends Swordman {
    private enum Weapon { SWORD, SPEAR }
    private Weapon weapon = Weapon.SWORD;

    public Knight(Side side) {
        super(side);
        hp += 40;
    }

    public void switchWeapon () {
        weapon = weapon == Weapon.SWORD ? Weapon.SPEAR : Weapon.SWORD;
    }

    private void spearAttack(Unit target) {
        target.hp -= 14;
    }

    @Override
    public void defaultAttack(Unit target) {
        if (weapon == Weapon.SWORD) {
            super.defaultAttack(target);
        } else {
            spearAttack(target);
        }
    }

		@Override
    public String toString() {
        return side.toString() + " 진영 기사";
    }
}

 

  • weapon이라는 신규 필드 및 enum클래스를 가지고 있고, 무기가 2개이니 switchWeapon이라는 메서드도 가지고 있다.
  • Swordman 클래스를 상속받아서, super를 쓰면 swordman의 생성자로 생성이 된다. 그리고 hp는 조상클래스의 필드 hp로 사용된다.

 

 

 

마법기사 클래스

public class MagicKnight extends Knight {
    public int mana = 60;
    public final int MANA_USAGE = 4;
    public MagicKnight(Side side) {
        super(side);
    }

    public void lighteningAttack (Unit[] targets) {
        for (Unit target : targets) {
            if (target instanceof MagicKnight) continue;
            if (mana < MANA_USAGE) break;
						System.out.printf("⚡️ → 💀 %s%n", target);
            target.hp -= 8;
            mana -= MANA_USAGE;
        }

    }

		@Override
    public String toString() {
        return side.toString() + " 진영 마법기사";
    }
}

 

  • 마나라는 신규 필드 및 신규공격 메서드를 가지고 있다.
  • 타겟을 배열로 받아서 광역 공격하는 코드가 있다.

 

 

말 클래스

public class Horse<T extends Unit> {
    private int extraHp;
    private T rider;

    public Horse(int extraHp) {
        this.extraHp = extraHp;
    }

    public void setRider(T rider) {
        this.rider = rider;
        rider.hp += extraHp;
    }

		@Override
    public String toString() {
        return "말 (추가체력: %d)".formatted(extraHp);
    }
}

 

  • 제네릭 클래스이고, Unit을 상속받는 클래스를 파라미터로 받는다.

 

 

				Swordman r_swordman1 = new Swordman(Side.RED);
        Knight r_knight1 = new Knight(Side.RED);
        Knight r_knight2 = new Knight(Side.RED);
        MagicKnight r_magicKnight1 = new MagicKnight(Side.RED);

        Knight b_knight1 = new Knight(Side.BLUE);
        MagicKnight b_magicKnight1 = new MagicKnight(Side.BLUE);
        MagicKnight b_magicKnight2 = new MagicKnight(Side.BLUE);

        Horse<Swordman> avante = new Horse<>(40);
        Horse<Knight> sonata = new Horse<>(50);

        avante.setRider(r_swordman1); // 🔴
        sonata.setRider(b_magicKnight1);

        r_swordman1.defaultAttack(b_knight1); // 🔴
        r_knight1.defaultAttack(b_magicKnight1);
        r_knight2.switchWeapon();
        r_knight2.defaultAttack(b_magicKnight2);

        b_magicKnight1.defaultAttack(r_swordman1);
        b_magicKnight2.lighteningAttack(new Unit[] {
                r_knight1,
                r_knight2,
                r_magicKnight1
        });

 

 

 

 

 

 

 

 

 

출처 

  •  
 

학습 페이지

 

www.inflearn.com