☕ Java

[Java] Day11 - 추상화 / 캡슐화 실습

harveydent 2023. 5. 18. 10:47
728x90

실습 1

프로그램 개요

class Pokemon
- String name
- int win 이긴횟수
- void hello() : 각각의 포켓몬마다 고유한 소리를 출력
- boolean game(Pokemon pokemon)
    -> pokemonA.game(pokemonB);
    홀홀 작은값이 이김
    짝짝 큰값이 이김
    홀짝,짝홀 홀수가 이김

class 생성시

1. abstract일까?
    1) 이 클래스의 객체가 필요한가?
    2) 추상메서드가 있나? == 오버라이딩을 강제해야하는 메서드가 있나?
        == 재정의해야하는 메서드가 있나?
2. 멤버변수 생성
    1) private
    2) getter,setter
3. 생성자
4. 메서드
    1) 오버라이딩(재정의)을 강제해야되나? => 추상메서드로 만들어야하나?
    2) '기능'을 보고, "INPUT,OUTPUT"을 생각하여 '메서드 시그니처' 작성

 

코드 구현

package class03;

abstract class Pokemon {
	private String name;
	private int win;
	
	Pokemon(String name) {
		this.name = name;
		this.win = 0;
	}
	
	abstract void hello();
	
	boolean game(Pokemon pokemon) {
		boolean flag = false;
		if (this.win == pokemon.win) {
			flag = true;
		} else if (this.win % 2 != 0 && pokemon.win % 2 != 0) {
			flag = this.win < pokemon.win ? true : false;
		} else if (this.win == 0 && pokemon.win % 2 == 0) {
			flag = this.win > pokemon.win ? true : false;
		} else {
			flag = this.win % 2 != 0 ? true : false;
		}
		if (flag == true) {
			System.out.println(this.name + " 이(가) 승리하였습니다.");
			this.setWin(this.win + 1);
			pokemon.hello();
		} else {
			System.out.println(pokemon.name + " 이(가) 승리하였습니다.");
			pokemon.setWin(pokemon.win + 1);
			this.hello();
		}
		return flag;
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public int getWin() {
		return win;
	}
	
	public void setWin(int win) {
		this.win = win;
	}
	
	@Override
	public String toString() {
		return "name=" + name + ", win=" + win ;
	}
	
}

class Pika extends Pokemon {
	Pika(String name) {
		super(name);
	}
	
	@Override
	void hello() {
		System.out.println("피카피카ㅠㅠ");
	}
}

class Pyree extends Pokemon {
	Pyree(String name) {
		super(name);
	}
	
	@Override
	void hello() {
		System.out.println("파이파이ㅠㅠ");
	}
}

class Tle extends Pokemon {
	Tle(String name) {
		super(name);
	}
	
	@Override
	void hello() {
		System.out.println("꼬북꼬북ㅠㅠ");
	}
}

public class Test01 {

	public static void main(String[] args) {
		
		Pokemon[] pk = new Pokemon[3];
		pk[0] = new Pika("피카츄");
		pk[1] = new Pyree("파이리");
		pk[2] = new Tle("꼬부기");
		
		pk[0].game(pk[1]);
		pk[0].game(pk[2]);
		pk[1].game(pk[0]);
		pk[1].game(pk[2]);
		pk[2].game(pk[0]);
		pk[2].game(pk[1]);
		
		System.out.println(pk[0]);
		System.out.println(pk[1]);
		System.out.println(pk[2]);
	}
}

 

실행 결과

실습 2

프로그램 개요

class Player
   최대 3마리의 포켓몬을 소유할수있다.
   Player 생성시 최초 소지 포켓몬은 무조건 피카츄이다.
   final static int maxIndex=3;
   int preIndex; // 1
   Pokemon[] data; // new Pokemon[maxIndex]
   // data[0]=new 피카츄();
   void play()
      // data에 저장된 포켓몬을 랜덤으로 2마리 선택하여 게임을 진행
      // 단, 2마리의 포켓몬이 서로 같은 포켓몬이면 더이상 진행하지않음 [Object최상위클래스->equals() 오버라이딩]
               클래스 타입이 같으면 같은 포켓몬
      // 서로 다른 포켓몬이면 포켓몬.game()을 진행함
      // 이긴 포켓몬의 울음소리가 console에 출력됨
      // 포켓몬.hello()

class Pokemon [abstract]
   String name;
   int win; // 이긴횟수
   void hello() // 울음소리. 하위클래스에 따라 수행되는 기능이 다름에 유의 [오버라이딩 강제->추상메서드]
   boolean game(Pokemon pokemon)
      // win이 홀홀일때는 작은쪽이 이김
      // win이 짝짝일때는 큰쪽이 이김
      // win이 홀짝일때는 홀수가 이김
      // win이 동일하다면 주어(주체)가 이김
      // 이후 이긴쪽의 win이 1 증가

1. 포켓몬 추가
2. 가진 포켓몬 전체 출력
3. 게임시키기
4. 프로그램 종료

 

코드 구현

package class04;

import java.util.Random;
import java.util.Scanner;

class Player {
	private final static int maxIndex = 3; // 최대 포켓몬 개수
	private int preIndex; // 현재 포켓몬 개수
	private Pokemon[] data; // 포켓몬 저장 배열
	private static Random rand = new Random();
		
	
//	Player() {
//		this.preIndex = 1; // 기본 포켓몬 1개
//		this.data = new Pokemon[maxIndex]; // 포켓몬 저장 배열 생성
//		this.data[0] = new Pika(); // 기본 피카츄 생성
//	}
	Player() {
		this.preIndex = 0; // 기본 포켓몬 개수
		this.data = new Pokemon[maxIndex]; // 포켓몬 저장 배열 생성
		this.data[this.preIndex++] = new Pika(); // 기본 피카츄 생성S
	}
	
	void play() {
		if (this.preIndex < 2) { // 저장된 포켓몬 개수가 2마리 미만일 떄 게임 불가
			System.out.println("저장된 포켓몬이 2마리 미만입니다.");
			return;
		}
		// 랜덤 인덱스 번호 생성
		int num1 = rand.nextInt(this.preIndex);
		int num2 = rand.nextInt(this.preIndex);
		if (this.data[num1].equals(this.data[num2])) { // 포켓몬 클래스 타입이 같을 때 게임 불가
		// ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
		// this.data[num1]가 equals()를 수행하는 주체
		// 타입 == 포켓몬		피카츄, 파이리, 메타몽, ...
		// 부모.메서드()했어도, 알아서
		// 자식이 구현한 메서드가 실행되는 현상
		//	== 동적바인딩 -> "다형성"이 실현되었다!
			// ☆ 실제 equals()를 수행하는 주체(주어)가
			// 피카츄, 파이리, 꼬부기, ...
			System.out.println("서로 같은 포켓몬입니다.");
			return;
		}
		if (this.data[num1].game(this.data[num2])) { // 주체 포켓몬이 이겼을 때
			this.data[num1].hello();
		} else { // 반대일 때
			this.data[num2].hello();
		}
	}
	
	void addPoke(int num) { // 포켓몬 생성
		if (num == 1) { // 1번 입력시 피카츄 생성
			this.data[this.preIndex] = new Pika();
			System.out.println(this.data[this.preIndex].getName() + " 생성이 완료되었습니다."); 
		} else if (num == 2) { // 2번 입력시 파이리 생성
			this.data[this.preIndex] = new Pyree();
			System.out.println(this.data[this.preIndex].getName() + " 생성이 완료되었습니다."); 
		} else { // 3번 입력시 꼬부기 생성
			this.data[this.preIndex] = new Tle();
			System.out.println(this.data[this.preIndex].getName() + " 생성이 완료되었습니다."); 
		}
		preIndex++; // 현재 포켓몬 개수 증가
	}
	
	public int getPreIndex() {
		return preIndex;
	}

	public void setPreIndex(int preIndex) {
		this.preIndex = preIndex;
	}

	public Pokemon[] getData() {
		return data;
	}

	public void setData(Pokemon[] data) {
		this.data = data;
	}

	public static int getMaxindex() {
		return maxIndex;
	}

	@Override
	public String toString() {
		String list = ""; // 현재 포켓몬 목록
		for (Pokemon poke : this.data) {
			if (poke == null) { // 현재 포켓몬이 있을 때
				break;
			}
			list += poke + "\n"; // 목록에 추가
		}
		return list;
	}
}

abstract class Pokemon {
	private String name;
	private int win;
	
	Pokemon(String name) {
		this.name = name;
		this.win = 0;
	}
	
	abstract void hello();
	
//	@Override
//	public boolean equals(Object obj) {
//		Pokemon poke = (Pokemon)obj; // 다운 캐스팅
//		if (this.name.equals(poke.name)) { // 주체 포켓몬 이름과 비교할 포켓몬 이름이 같을 때
//			return true;
//		}
//		return false;
//	}

	boolean game(Pokemon pokemon) {
		boolean flag = false;
		if (this.win == pokemon.win) {
			flag = true;
		} else if (this.win % 2 != 0 && pokemon.win % 2 != 0) {
			flag = this.win < pokemon.win ? true : false;
		} else if (this.win == 0 && pokemon.win % 2 == 0) {
			flag = this.win > pokemon.win ? true : false;
		} else {
			flag = this.win % 2 != 0 ? true : false;
		}
		if (flag == true) {
			System.out.println(this.name + " 이(가) 승리하였습니다.");
			this.setWin(this.win + 1);
		} else {
			System.out.println(pokemon.name + " 이(가) 승리하였습니다.");
			pokemon.setWin(pokemon.win + 1);
		}
		return flag;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getWin() {
		return win;
	}

	public void setWin(int win) {
		this.win = win;
	}

	@Override
	public String toString() {
		return name + " win=[" + win + "]";
	}
}

class Pika extends Pokemon {
	Pika() {
		super("피카츄");
	}
	
	@Override
	void hello() {
		System.out.println("피카피카");
	}

	// ★★★★★
	@Override
	public boolean equals(Object obj) {
		if (obj instanceof Pika) { // obj 가 Pika를 상속받는 클래스인지 확인
			return true;
		}
		return false;
	}
}

class Pyree extends Pokemon {
	Pyree() {
		super("파이리");
	}
	
	@Override
	void hello() {
		System.out.println("파이파이");
	}
	
	// ★★★★★
	@Override
	public boolean equals(Object obj) {
		if (obj instanceof Pyree) { // obj 가 Pyree를 상속받는 클래스인지 확인
			return true;
		}
		return false;
	}
}

class Tle extends Pokemon {
	Tle() {
		super("꼬부기");
	}
	
	@Override
	void hello() {
		System.out.println("꼬북꼬북");
	}
	
	// ★★★★★
	@Override
	public boolean equals(Object obj) {
		if (obj instanceof Tle) { // obj 가 Tle를 상속받는 클래스인지 확인
			return true;
		}
		return false;
	}
}

public class Test01 {

	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		
		Player player = new Player();
		
		String menu = "===================\n"
					+ "1. 포켓몬 추가\n"
					+ "2. 가진 포켓몬 전체 출력\n"
					+ "3. 게임시키기\n"
					+ "4. 프로그램 종료\n"
					+ "===================";
		
		String createPoke = "생성할 포켓몬을 선택 해 주세요.\n"
						+ "1. 피카츄\n"
						+ "2. 파이리\n"
						+ "3. 꼬부기";
		
		int action;
		
		while (true) {
			System.out.println(menu); // 메뉴 출력
			action = sc.nextInt();
			if (action == 4) { // 4번 입력시 프로그램 종료
				System.out.println("프로그램 종료");
				break;
			} else if (action == 1) { // 1번 포켓몬 추가
				if (player.getPreIndex() >= Player.getMaxindex()) { // 현재 포켓몬 개수가 최대 포켓몬 개수보다 크거나 같을 때
					System.out.println("최대 " + Player.getMaxindex() + "마리의 포켓몬을 소유할 수 있습니다.");
					continue;
				}
				while (true) {
					System.out.println(createPoke);
					action = sc.nextInt();
					if (action < 1 || action > 3) {
						System.out.println("잘못 입력하셨습니다.");
						continue;
					}
					player.addPoke(action);
					break;
				}
			} else if (action == 2) {
				System.out.println(player.toString());
			} else if (action == 3) {
				player.play();
			} else {
				System.out.println("잘못 입력하셨습니다.");
			}
		}
	}
}

GitHub

https://github.com/Qkrwnsgus0522/Java

 

GitHub - Qkrwnsgus0522/Java

Contribute to Qkrwnsgus0522/Java development by creating an account on GitHub.

github.com

 

728x90