객체 지향 프로그램에서 하나의 클래스를 정의할 때 클래스의 멤버 변수를 선언하고 메서드로 기능을 선언한다.
사람을 객체로 만들고 클래스화 해서
사람의 속성들을 멤버 변수를 선언하고,
메서드로 사람의 기능을 선언한다.
여기까지는 좋다. 사람의 속성이나 (키, 몸무게 등) 기능들 (걷는다, 밥을 먹는다) 까지 생각하는 것은 무리가 없어 보인다. 자바로 충분히 만들 수 있다.
그러면 이제 사람 사이의 상호작용까지 자바의 클래스로 표현할 수 있을까? 라는 의문을 갖게 된다.
사람 사이의 상호작용 이거는 쉽지않을 것 같다.
어디 사람사이의 상호작용이 하나 두개야? 사람간에 일어나는 물질적,정신적 일을 클래스에 다 기록한다면 엄청난 정보의 기록이 될 것이다. 상상이 안간다.
그러니까 프로그래밍에서는 당장 필요한 부분만 구현하면 된다. 가장 기초적인 내용을 구현하는데서 시작하는게 좋을 것 같다.
이번에는 두 사람의 무도가를 클래스로 만들어 본다. 두 사람이 펀치와 킥을 주고 받는 것은 단순한 행동이니까 충분히 가능할 것 같다. 격투 게임의 캐릭터를 만드는 것과 비슷하다.
무도가 클래스를 만들어 보자.
public class Fighter{
String name; // 선수이름
int healthPoint; // HP 체력
int defensePoint; // DP 방어력
int punchPower; // 펀치의 파워
int kickPower; // 킥의 파워
}
무도가는 체력과 방어력이 있고, 펀치와 킥의 파워가 기본 능력치다. (어디서 많이 본 stat이다) 사실 격투 게임 캐릭터의 능력치란 것이 기본은 비슷하다. HP (체력)이 있고 상대방의 공격이 들어오면 방어력만큼 공격력에서 깎고 HP를 삭제한다. 여기에 랜덤 확률과 다른 기법을 추가해서 게임을 예측 불가하고 다이나믹하게 만든다. 이 정도는 게임을 좋아하는 사람이면 알만한 내용이다.
그 다음에 메서드를 추가한다. 한 사람이 공격을 하면 상대방은 데미지를 입을 것이고, 서로 펀치와 킥을 주고 받다가 먼저 HP가 0이 되는 무도가가 쓰러지면서 경기가 끝날 것이다. 두 객체간의 상호 작용이 일어나는 것을 메서드로 구현한다.
생성자부터 만들어 준다.
public class Fighter{
String name; // 선수 이름
int healthPoint; // HP 체력
int defensePoint; // DP 방어력
int punchPower; // 펀치의 파워
int kickPower; // 킥의 파워
Fighter(Strng name, int hp, int dp, int pp, int kp){
this.name = name;
this.healthPoint = hp;
this.defensePoint = dp;
this.punchPower = pp;
this.kickPower = kp;
}
}
매개변수와 멤버변수 이름이 다르더라도 this. 를 작성하여 Fighter 클래스의 인스턴스 속성을 명시해준다.
다음은 메서드를 구현할 차례다.
간단하게 punch 와 kick 으로 타격한다고 한다. 무도가 A가 무도가 B를 타격하면 방어력을 제외한 수치가 순수 데미지이고 상대방의 HP(체력)에서 데미지 만큼 깎는다. HP가 0보다 작게 되면 Knockdown 을 당하고 쓰러진다.
punch 메서드는 상대방 인스턴스를 참조 매개변수로 받는다. 그러면 실제 상대방 인스턴스의 멤버 변수를 조작할 수 있게된다. opponent.healthPoint 를 damage 만큼 깎는다. kick 메서드도 공격력만 차이가 있을 뿐 똑같은 구조다.
isKnockDown 메서드는 공격을 당하고 체력이 0보다 적은지 검사한다. 0보다 작으면 true 를 반환하여 프로그램을 종료한다.
이제 main 메서드에서 두 객체에 싸움을 붙이는 시간이 왔다.
Fighter 클래스로 두명의 전사를 불러왔다. Bruce Lee (이소룡)과 Mike Tison(마이크 타이슨)이다. 아쉽게도 두분은 시대가 엇나가서 실제 맞붙는걸 보진 못한다. 마이크 타이슨은 지금도 인스타에 핫하던데,,, (팔로우 했음)
Bruce Lee는 킥공격력을 더 주고 Mike Tison 은 펀치에 공격력을 더 줘서 초기화 시키고 인스턴스를 생성한다.
한 쪽이 쓰러져야 끝날 테니까 while 무한루프를 돌다가 한쪽의 HP가 0이 되면 종료하도록 한다. (isKnockDown) -> break;
한쪽은 킥이 세고 한쪽은 펀치가 세니까 공정하게 번갈아가면서 공격하도록 한다.
결국 3회에 걸친 루프를 돌고 타이슨이 승리했다! 하긴 이소룡은 영춘권을 배운 영화배우이고, 타이슨은 전설의 복서였으니...
라고 했지만 1차원 적인 경기였기에 초기값을 어떻게 설정하느냐에 따라 승패는 갈린다. 아무래도 타이슨은 아직 살아있는 전설이라 체력포인트에 초기값을 더 줬기 때문이다. 게임을 좀 더 재미있게 하려면 Random 클래스를 사용해서 회피나 크리티컬을 확률을 주면 된다.
객체간의 관계를 표현하는 방법은 여러가지가 있다. 객체의 종류도 다를 수 있을 것이고. 이것 저것 설계를 해보자. 어떤 객체를 만들지 상상해보고 구현해보자.