본문 바로가기
JAVA

7. 오버로딩

by 김마리님 2020. 3. 27.

★크래프트라는 게임이 있다. 그 게임을 예시로 오버로딩의 예를 보도록 하자.

프로토스의 유닛을 보자. 질럿, 드라군, 다크템플러, 리버가 있다고 가정한다.

(여러가지 기능이 있지만 이건 공부하는 용이니까) 크게 세가지의 변수를 지정해보자

 

이름, 체력, 공격력.

 

일단 질럿만 보자.

이름은 유닛이 인스턴스화 되면서 지정될 것이다. 가령, 1번 질럿이라던가 2번 질럿이라던가.. 그 질럿의 이름은 인스턴스가 사라지기 전까지 변하지 않는 값일 것이다. 그러면, 이 값은 상수일터이다.

체력은 모든 질럿이 처음에는 같게 태어나지만, 그 질럿이 얼마나 공격 당하고 치유받고 하는가에 따라서 체력은 유동적으로 바뀌게 된다. 따라서, 변수의 초기화는 서로 같게 하지만, 유동적으로 변하는 변수로 선언하자.

공격력은, 잘 생각해보자. 스타크래프트는 포지를 통해 질럿의 공격력 업그레이드가 가능하다.

만약 공격력 변수가 클래스로 선언되어 heap 공간에 생성되면, 질럿이 인스턴스화가 되어야 비로소 메모리에 공격력 변수가 선언될 것이다. 하지만 질럿이 없어도 포지에서 공격력 업그레이드는 가능하다. 그렇기 때문에 질럿의 공력력은 static 공간에서 선언되어야 질럿이 없어도 업그레이드가 가능하다.

 

따라서 유닛에 대한 변수를 다음과 같이 지정해야한다.

class Zealot {
	final String NAME;
	int hp;
	static int attack = 10;

	public Zealot(String name) {
		this.NAME = name;
		this.hp = 100;
	}
}

class Dragoon {
	final String NAME;
	int hp;
	static int attack = 15;

	public Dragoon(String name) {
		this.NAME = name;
		this.hp = 100;
	}
}

class DarkTempler {
	final String NAME;
	int hp;
	static int attack = 50;

	public DarkTempler(String name) {
		this.NAME = name;
		this.hp = 100;
	}
}

class River {
	final String NAME;
	int hp;
	static int attack = 50;

	public River(String name) {
		this.NAME = name;
		this.hp = 100;
	}
}

 

 

이름은 한 번 지정되면 인스턴스가 사라지기 전까지 유지되는 이름이다. 따라서, 변수가 지정되면 이것이 변하지 않도록 조치해야하는데, 그것을 도와주는 레퍼런스가 final이다. final이 붙은 변수가 있는 메모리 공간은 선언과 동시에 READ ONLY 공간으로 설정되어서 수정할 수 없게 된다. 이런 데이터를 불변 데이터라고 한다. 이 때, 개발자들 간에 협약이 있는데, 이런 불변 데이터는 반드시 대문자로 입력하도록 한다.

 

다음, 질럿과 드라군을 생성해보자.

	public static void main(String[] args) {
		Zealot z1 = new Zealot("1번 질럿");
		Zealot z2 = new Zealot("2번 질럿");
		Dragoon d1 = new Dragoon("1번 드라군");
		Dragoon d2 = new Dragoon("2번 드라군");

 이후, 질럿이 드라군을 공격하는 매서드를 만들어보자.

public class GameStart {

	// 질럿 => 드라군
	static void attack(Zealot u1, Dragoon u2) {
		u2.hp = u2.hp - u1.attack;
		System.out.println(u2.NAME + "이 공격당하고 있습니다.");
		System.out.println(u2.NAME + "의 체력은" + u2.hp + "입니다.");
	}

다음과 같이 드라군이 질럿에게 맞고 있다는 문구가 출력된다.

하지만, 드라군도 마냥 무기를 접진 않고 질럿을 공격할 것이다. 질럿을 공격하는 매서드를 만들어보자.

	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 + "입니다.");
	}

분명 질럿이 드라군을 공격하는 것과, 드라군이 질럿을 공격하는 것은 서로 다른 내용이다. 그래서 다른 매서드를 만들어야 할 것 같지만, 예시를 보면 같은 attack 매서드를 사용하고 있다. 

이것이 오버로딩이다. 들어가는 매개변수가 다르면 같은 매서드 이름을 공유하면서 사용할 수 있다. 이 오버로딩 기법은 사용자가 한가지 함수만 외워도 된다는 장점을 부여한다.

다음 함수는 매개변수의 갯수는 같지만 매개변수의 데이터 타입이 다르기 때문에 다른 매개변수로 취급되는 것이다.

물론 매개변수의 갯수가 달라도 오버로딩이 된다.

 

질럿과 드라군.. 만 있으면 이렇게 오버로딩이 간단한데, 다크템플러와 리버가 온다고 가정하자.

	static void attack(Zealot u1, Dragoon u2) {
		u2.hp = u2.hp - u1.attack;
		System.out.println(u2.NAME + "이 공격당하고 있습니다.");
		System.out.println(u2.NAME + "의 체력은" + u2.hp + "입니다.");
	}

	static void attack(Zealot u1, Zealot u2) {
		u2.hp = u2.hp - u1.attack;
		System.out.println(u2.NAME + "이 공격당하고 있습니다.");
		System.out.println(u2.NAME + "의 체력은" + u2.hp + "입니다.");
	}
	
	static void attack(Zealot u1, DarkTempler u2) {
		u2.hp = u2.hp - u1.attack;
		System.out.println(u2.NAME + "이 공격당하고 있습니다.");
		System.out.println(u2.NAME + "의 체력은" + u2.hp + "입니다.");
	}
	
	static void attack(Zealot u1, River u2) {
		u2.hp = u2.hp - u1.attack;
		System.out.println(u2.NAME + "이 공격당하고 있습니다.");
		System.out.println(u2.NAME + "의 체력은" + u2.hp + "입니다.");
	}

이렇게 질럿만 해도 매서드가 4개가 생성되는데, 드라군도 4개... 다크템플러도 4개.. 리버도 4개.. 이렇게 계속 끝없이 늘어나게 되는데, 이것이 오버로딩의 한계이다.

따라서, 오버로딩은 끝이 보이는 프로그램에만 사용하는 것이 좋다.

반응형

'JAVA' 카테고리의 다른 글

9. 매서드 오버라이딩  (0) 2020.03.30
8. 상속  (0) 2020.03.30
6. 생성자  (0) 2020.03.27
클래스, 객체, 인스턴스  (0) 2020.03.27
JAVA 실습 6. while, break, continue를 이용한 난수맞추기 게임 만들기  (0) 2020.03.24