오늘 배운 문법 정리 ✍
제어자 란 ?
: 클래스, 변수, 메서드의 선언부에 사용되어 부가적인 의미를 부여하는 것으로
접근 제어자와 그 외의 제어자( 오늘 배운 것은 static ) 로 나뉜다.
접근 제어자
: 클래스, 변수, 메서드, 생성자에 사용되며, 외부로부터의 접근을 제한한다.
: 외부로부터 데이터를 보호하고, 내부적으로만 사용되는 부분을 감추기 위해서 사용한다.
접근 제어자의 종류
1) private : "같은 클래스" 내에서만 접근이 가능하다.
2) default : "같은 패키지" 내에서만 접근이 가능하다.
3) protected : 같은 패키지 내에서, 그리고 다른 패키지의 자식클래스에서만 접근이
가능하다.
4) public : 접근 제한이 없다.
static
: 일반적인 인스턴스 변수들과는 달리 프로그램 로딩시에 static 영역의 메모리에
올라가기 때문에 객체를 생성하지 않고 사용할 수 있다.
보통 프로그램 전반에 걸친 전역변수나 공용으로 사용해야 할 변수가 필요할 때
사용한다.
// 카드 생성 예제 ✅
package day04.package1;
public class Card {
private Integer num; // 카드 번호 : 1~10
private String type; // 카드 모양 : 하트, 다이아, 클로버, 스페이드
private static Integer width; // 가로 길이는 모든 카드가 동일하므로 static 을 사용
private static Integer height; // 세로 길이는 모든 카드가 동일하므로 static 을 사용
public Card(Integer num, String type, Integer width, Integer height) {
this.num = num;
this.type = type;
this.width = width;
this.height = height;
}
@Override
public String toString() {
return "Card{" +
"num=" + num +
", type='" + type + '\'' +
", width='" + width + '\'' +
", height='" + height + '\'' +
'}';
}
}
package day04.package2;
import day04.package1.Card;
public class Main2 {
public static void main(String[] args) {
Card heart01 = new Card(1,"하트",50,80);
Card heart02 = new Card(2,"하트",50,80);
Card heart03 = new Card(3,"하트",100,160);
// heart03에서 가로, 세로 길이를 변경하여 생성해줬는데;
// 가로, 세로 길이는 static 으로 서로 공유해서 사용토록 설정이 되어 있기 때문에
// hear01, heart02 의 가로, 세로 길이도 heart03 생성 시 입력해 준 값으로 덮어쓰여지게 된다.
System.out.println(heart01.toString());
System.out.println(heart02.toString());
System.out.println(heart03.toString());
}
}
💯 출력결과 💯
Card{num=1, type='하트', width='100', height='160'}
Card{num=2, type='하트', width='100', height='160'}
Card{num=3, type='하트', width='100', height='160'}
위 코드를 실행한 결과 : heart03
에서 가로, 세로 길이를 기존의 카드와 다르게 변경하여 생성해줬을때,
hear01
, heart02
의 가로, 세로 길이도 같이 변경된 것을 확인할 수 있었다.
이것은 가로, 세로 길이에 static 제어자가 사용되었기 때문에, 서로 공유하고 있어서 마지막에 변수를 생성해줄때 부여한 값으로 기존 변수들도 덮어쓰여진 것이다.
이처럼, static 제어자를 사용하면 공용으로 해당 변수 또는 메서드를 사용하게 된다.
Getter 와 Setter
: 다음으로 변수를 생성할 때 "private 접근 제어자" 를 사용하면, 다른 패키지,
다른 클래스에서는 해당 변수로 접근을 할 수가 없게 된다.
: 하지만 해당 변수에 접근을 하고 싶다면 어떻게 해야 될까❓
접근하는 방법으로는 메서드를 만들어 줘서 메서드를 통해 해당 변수에 접근을 할 수
있는데, 이때 사용하는 메서드가 바로 Getter
와 Setter
다.
: Setter
메서드는 주로 데이터를 변경하는 역할을 하고, Getter
메서드는 주로
데이터를 읽어오는 역할을 수행한다.
⛄ 실습 하기 ( 야바위 게임 만들기 ) ⛄
👉 게임 설명
- 1 ~ 3의 숫자에 "정답", "꽝", "폭탄" 이 랜덤하게 섞여있다.
- 두 명의 플레이어가 있다.(기본 보유 하트 개수 : 5개)
- 1 ~ 3 중 게임 플레이어가 원하는 숫자를 차례로 번갈아 가면서 입력한다.
- 고른 숫자가
"정답" 이면 점수가 1 증가한다.
"꽝" 이면 해당 플레이어의 하트가 1개 줄어든다.
"폭탄" 이면 점수가 1 감소하고, 해당 플레이어의 하트가 1개 줄어든다.- 게임 클리어 조건 : 점수가 3점이 되면 게임 클리어 메시지와 함께 게임 종료
- 두 명의 플레이어 모두 하트가 0이 될 시 게임 오버 메시지와 함께 게임 종료
- 플레이의 점수는 0 이하로 내려가지 않는다.
// 야바위 기본 정보 및 기능 클래스 ✅
package day04.package1;
public class Yabawi {
private static Integer score; // 점수 (플레이어 간 공유)
private Integer heart; // 하트
private Boolean success; // 게임 클리어 기준
private Boolean die; // 하트 소진 기준
public Yabawi(Integer score, Integer heart) {
this.score = score;
this.heart = heart;
}
// 숫자 고르기 기능 ✅
public void pickUp(Integer num) {
if(num == 3) {
System.out.println("정답을 고르셨습니다. 점수가 1 증가합니다.");
scoreChange(3);
} else if(num == 2) {
System.out.println("꽝을 고르셨습니다. 하트 개수가 1 감소합니다.");
heartDown(2);
} else if(num == 1) {
System.out.println("폭탄을 고르셨습니다. 하트와 점수가 1씩 감소합니다.");
scoreChange(1);
System.out.println();
heartDown(1);
}
}
// 점수 변동 기능 ✅
Integer scoreChange(Integer num) {
if(num == 3) {
this.score = score + 1;
} else if(num == 1) {
this.score = score - 1;
}
if(this.score < 0) { // 점수는 0 미만으로 떨어지지 않음
this.score = 0;
}
System.out.print("현재 점수 : " + this.score);
return score;
}
// 하트 감소 기능 ✅
Integer heartDown(Integer num) {
if(num == 2) {
this.heart = heart - 1;
} else if(num == 1) {
this.heart = heart - 1;
}
System.out.println("현재 하트 : " + this.heart);
return heart;
}
// 하트 소진 기준 ✅
public Boolean heartdie(){
if(this.heart == 0) {
this.die = true;
} else {
this.die = false;
}
return die;
}
// 게임 클리어 기준 ✅
public Boolean gameSuccess() {
if(this.score == 3) {
System.out.println("야바위 게임을 클리어 하셨습니다.");
this.success = true;
} else {
this.success = false;
}
return success;
}
}
// 게임 플레이 클래스 ✅
package day04.package2;
import day04.package1.Yabawi;
import java.util.Scanner;
public class Player {
public static void main(String[] args) {
Yabawi player01 = new Yabawi(0, 5);
Yabawi player02 = new Yabawi(0, 5);
Scanner pl = new Scanner(System.in);
while(true) {
// 1 ~ 3의 숫자를 담은 박스 배열 생성
int[] box = new int[3];
for(int i=0; i<3; i++) {
box[i] = i+1;
}
// 박스안의 값을 랜덤하게 섞어줌 ✅
for(int i=0; i<100; i++) {
int j=(int)(Math.random()*3);
int temp = box[0];
box[0] = box[j];
box[j] = temp;
}
System.out.print("Player01님 1, 2, 3의 숫자 중 한개를 고르시오 : ");
int number = pl.nextInt();
player01.pickUp(box[number-1]);
System.out.println();
if(player01.gameSuccess()) {
break;
}
System.out.println();
System.out.print("Player02님 1, 2, 3의 숫자 중 한개를 고르시오 : ");
int number2 = pl.nextInt();
player02.pickUp(box[number2-1]);
System.out.println();
if(player02.gameSuccess()) {
break;
}
if(player01.heartdie() && player02.heartdie()) {
System.out.println("모든 플레이어가 하트를 소진하여 게임을 종료합니다.");
break;
}
}
}
}
💯 출력결과 💯
Player01님 1, 2, 3의 숫자 중 한개를 고르시오 : 2
정답을 고르셨습니다. 점수가 1 증가합니다.
현재 점수 : 1
Player02님 1, 2, 3의 숫자 중 한개를 고르시오 : 3
꽝을 고르셨습니다. 하트 개수가 1 감소합니다.
현재 하트 : 4
Player01님 1, 2, 3의 숫자 중 한개를 고르시오 : 3
정답을 고르셨습니다. 점수가 1 증가합니다.
현재 점수 : 2
Player02님 1, 2, 3의 숫자 중 한개를 고르시오 : 3
정답을 고르셨습니다. 점수가 1 증가합니다.
현재 점수 : 3
야바위 게임을 클리어 하셨습니다.
야바위 문제는 사실 가장 헷갈렸던게 말 그대로 야바위를 구현하는거였다. 3개의 랜덤한 숫자를 입력받는데 입력 받을때마다 "정답", "꽝", "폭탄" 의 번호가 달라지는 것이 처음에는 이해가 되지 않았다.
그래서 나는 먼저, 야바위를 생각하지 않고, 1 ~ 3에 숫자에 "정답", "꽝", "폭탄" 을 고정으로 입력시키게 구현한 뒤에 야바위 부분을 추가하여 해당 코드를 작성할 수 있었다.
야바위 기능은 지난 수업 시간에 실시했던 로또 번호 생성기의 원리를 가지고 와서 구현하였다.
오늘의 느낀점 👀
오늘은 접근 제어자와, Getter/Setter 메서드를 학습한 뒤 그동안 배운 문법들을 활용하여 실습 문제를 풀어봤다. 오늘로써 자바 프로그래밍을 시작한 지 4일차인데, 점점 클래스와 객체, 메서드 등에 대하여 이해가 되고 있는 것 같다.
처음에는 간단한 코드도 구현을 못했다면, 지금은 벌써 간단한 게임을 구현할 정도로 실력이 오른 내 모습을 보며 앞으로도 더욱 열심히 해야겠다는 의지가 생긴다. 🔥🔥
자바도 결국엔 언어이다. 언어는 학습하면 할수록 실력이 늘 수 밖에 없다고 생각한다. 결국, 중요한 것은 꾸준히 노력하는 것이 아닌가 싶다. 1주일 뒤 성장한 내 모습을 상상하며 오늘도 열심히 복습 및 문제를 풀어볼 예정이다. 🧐