얄코의 제대로 파는 자바/섹션7 클래스와 자료형
다음 섹션용 게임 예제
백엔드 개발자
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