Unit 클래스
public abstract class Unit {
protected String name;
protected int hp;
protected int attackPower;
public Unit(String name, int hp, int attackPower) {
this.name = name;
this.hp = hp;
this.attackPower = attackPower;
}
public void setHp(int hp) {
this.hp = hp;
}
public String getName() {
return this.name;
}
public int getHp() {
return this.hp;
}
public int getAttackPower() {
return this.attackPower;
}
}
Marine 클래스
public class Marine extends Unit implements Attackable{
public Marine(String name, int hp, int attackPower) {
super(name, hp, attackPower);
}
public void attack(Unit unit) {
System.out.println(this.name + "이 " + unit.getName() + "을 원거리 공격합니다.");
unit.setHp(unit.getHp() - this.attackPower);
}
}
Medic 클래스
public class Medic extends Unit {
public Medic(String name, int hp, int attackPower){
super(name, hp, attackPower);
}
}
List<Unit> list = new .....
for(Unit unit : list)
((Attackable) unit).attack(unit); // ?
attackable 이유
((Attackable) unit).attack(unit);에서 (Attackable)로 형 변환을 하는 이유는, Unit 클래스가 Attackable 인터페이스를 구현하고 있는지 여부에 따라 attack 메서드를 호출할 수 있는지 확인하기 위함입니다.
이를 좀 더 자세히 설명하자면:
- Unit 클래스는 Attackable 인터페이스를 구현하지 않습니다.
반면, Marine 클래스는 Attackable을 구현하고 있습니다.- Attackable 인터페이스는 attack 메서드를 정의하고 있으며, 이를 구현하는 클래스는 실제로 attack 메서드를 제공해야 합니다.
- List은 Unit 타입의 객체들을 저장하는 리스트입니다. 하지만 Unit 클래스는 Attackable을 구현하지 않으므로, List의 객체들을 직접 Attackable 타입으로 다룰 수 없습니다.
- 따라서 unit이 Attackable을 구현하는 객체인지 확인하고, 맞다면 attack 메서드를 호출할 수 있도록 형 변환을 해야 합니다.
List<Unit> list = new....
for(Unit unit : list)
if (unit instanceof Attackable)
((Attackable) unit).attack(unit); // O
- if (unit instanceof Attackable)은 unit이 Attackable 인터페이스를 구현하는 객체인지 확인합니다.
- ((Attackable) unit).attack(unit);는 unit이 실제로 Attackable을 구현하고 있는 경우에만 attack 메서드를 호출합니다.
- attack 메서드는 대상 Unit을 공격하기 위한 메서드입니다. 따라서 현재 객체(unit)가 다른 unit을 공격하는 방식으로 메서드를 호출합니다.
- 전체적으로, ((Attackable) unit).attack(unit);에서 형 변환을 사용하는 이유는 Unit 타입의 객체가 Attackable 타입으로 다뤄질 때만 attack 메서드를 호출할 수 있기 때문입니다. 이 접근 방식은 자바의 다형성과 타입 체크를 활용하여 코드의 안전성을 높이는 방법 중 하나입니다.
for (Unit unit : list) {
if (unit instanceof Attackable) {
((Attackable) unit).attack(unit);
}
}
결론