https://itstudy-mary.tistory.com/68
오버로딩을 하면서 ★의 유닛만들기를 했었다.
이 때 오버로딩의 한계를 정의했는데, 이 한계를 없애는 실습이다.
여기서 우리는 세 개의 변수를 보았었다.
공격력, 생명력, 이름.
이를 오버로딩 하기 위해 다음과 같은 코드를 입력했었다.
static void attack(Dragoon u1, Zealot u2) {
u2.hp = u2.hp - u1.attack;
System.out.println(u2.NAME + "이 공격당하고 있습니다.");
System.out.println(u2.NAME + "의 체력은" + u2.hp + "입니다.");
}
이를 오버라이딩 할 것이다.
여기서 바뀌는 값과 바뀌지 않을 값을 보자.
바뀌지 않을 값은 이름, 바뀔 값은 공격력과 체력이다. 이들은 매서드가 아니라 변수이기 때문에 오버라이딩을 이용해 변수값을 간접적으로 호출해야한다.
따라서, 이름은 get, 그리고 공격력과 체력은 get과 set함수로 선언하자.
abstract class Protoss {
abstract String getName();
abstract int getAttack();
abstract void setAttack(int a);
abstract int getHp();
abstract void setHp(int a);
}
오버라이딩을 위해 생성한 부모 클래스이다.
생각을 해보자. ★크래프트의 유닛 중에 "프로토스" 라는 이름을 가진 유닛이 있는가? 종족 말고 유닛! 유닛 이름이 프로토스인 것은 없으므로, 이를 추상화 해야한다. 따라서 abstract를 붙여 추상화를 시키자. 대신 내부에 있는 모든 클래스를 오버라이딩 해서 실체화 시켜야 한다.
일단 질럿을 만드는 코드를 수정해보았다.
class Zealot extends Unit {
static int attack = 10;
final String NAME;
int hp = 100;
public Zealot(String name) {
this.NAME = name;
}
@Override
String getName() {
return NAME;
}
@Override
int getHp() {
return hp;
}
@Override
int getAttack() {
return attack;
}
@Override
void setHp(int hp) {
this.hp = hp;
}
@Override
void setAttack(int attack) {
this.attack = attack;
}
}
생성자를 통해 이름을 받고, 그 받은 이름은 getNAME으로 들어갈 것이다.
나머지 역시 마찬가지다 get 을 통해 이름을 메인 스택 메모리로 호출하고 set으로 호출된 heap 혹은 static 메모리 내의 HP 나 공격력값을 수정한다.
this를 통해 객체를 지정하고 수정된 값을 받으므로, 나머지 유닛도 똑같은 방식으로 오버라이딩을 지정해준다. (이건 생략!)
오버라이딩 된 값은 다음과 같이 새로운 매서드로 만들어주자.
static void attack(Unit u1, Unit u2) {
int hp = u2.getHp() - u1.getAttack();
u2.setHp(hp);
System.out.println(u2.getName() + "이 공격당하고 있습니다.");
System.out.println(u2.getName() + "의 체력은" + hp + "입니다.");
}
마찬가지로, 이 값들은 직접 변수로 직접 호출할 수 없어서 함수의 결과값으로 간접 호출한다. 값을 변경해야할 경우엔 일시적으로 새로운 변수(hp)를 만들고, 그 변수를 함수를 통해 다시 집어넣어서 값을 변화시켜야만 한다.
(다음과 같이 함수를 직접 변경하는 것이 불가능 하기 때문이다.)
'JAVA' 카테고리의 다른 글
10. 추상 클래스/추상 매서드 (0) | 2020.03.31 |
---|---|
라이브러리(lombok) 설치하기 (0) | 2020.03.31 |
9. 매서드 오버라이딩 (0) | 2020.03.30 |
8. 상속 (0) | 2020.03.30 |
7. 오버로딩 (0) | 2020.03.27 |