public class lecture3_SaveBox_executionClass {
public static void main(String[] args) {
SaveBox pig1 = new SaveBox();
SaveBox pig2 = new SaveBox();
// int a와 int b가 같은 int지만 서로 다른 a와 b인 것처럼, 같은 Svaebox 클래스지만 pig1과 pig2는 다르다. Savebox 클래스의 객체변수 pig1, pig2.
// 즉, pig1도 deposit 메소드를 하고, pig2도 deposit 메소드를 하지만 둘은 서로 다른 세계다.
// OOP : (Svabox = 우주, pig = 내 통장, depoist = 로또 당첨. 나와 다른 평행우주에 살고 있는 또 다른 내가 로또에 당첨되는 것은 서로 별개다.)
// 객체지향 기법이라 이름을 붙인 만큼 현실 세계에 반영시켜 이해를 해보면 쉽다.
pig1.deposit(100); // 100 // pig1 클래스에서 deposit 메소드를 실행해. (deposit 메소드는 int를 인풋 파라미터로 받음.)
pig1.deposit(500); // 600
pig1.deposit(200); // 800
pig1.deposit(300); // 1100
pig1.deposit(500); // 1600
pig2.deposit(20000);
pig1.withdraw(); // 1600
pig2.withdraw(); // 2000
pig1.coinAmount = 200;
// 메소드를 불러오지 않고 pig1 클래스의 coinAmount라는 변수에 직접 데이터를 넣는다. 실제로 작동한다.
// OOP : (내 우주(SaveBox) 밖의 전지적인 능력자가 내 통장(pig2) 잔고를 강제로 200원으로 바꾼다.)
// OOP : (그래서 나는 이걸 막기 위해 private라는 키워드로 보호막을 쳐서 보호한다. - 정보은닉)
// 1. 일반적으로 객체 내부의 데이터는 외부에서 접근 못하게 한다. - 자바는 이쪽을 따르는게 업계의 룰. / 파이썬에서는 그냥 직접 접근하는 것이 업계의 룰.
// 2. 단, 현대 프로그래밍 기법에서는 필요에 의해서 접근을 허용한다. setter, getter 개념을 따른다. (자바쪽 업계의 룰)
// 이것 막기 위해 클래스 상에 private int coinAmount로 선언한다. 이렇게 하면 메소드로만 접근이 가능하다.
pig1.withdraw();
// 위에 pig1.coinAmount = 200에 의해 강제로 200원으로 값이 바뀌어 200이 출력될거다. SaveBox 클래스에 가서 private을 붙여보고 어떻게 되는지 다시 출력해보자.
}
}
결과 :
모든 금액의 합계는 1600입니다.
모든 금액의 합계는 20000입니다.
모든 금액의 합계는 200입니다.
결과(priviate int coinAmount) :
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The field SaveBox.coinAmount is not visible
at lecture3_SaveBox_executionClass.main(lecture3_SaveBox_executionClass.java:25)
25번 라인 pig1.coinAmount = 200; 이 강제로 coinAmount의 데이터에 접근하려 했지만 private로 보호 받고 있기 때문에 에러 발생.
public class SaveBox {
// int coinAmount = 0;
private int coinAmount = 0;
// 일반적인 사용 방법. 해당 클래스 내부의 변수와 인풋 파라미터의 이름을 구분지어 사용한다.
// public void deposit(int inputCoins) {
// coinAmount = coinAmount + inputCoins;
// // coinAmount -> SaveBox 내의 변수
// // inputCoins -> 인풋 파라미터
// }
// 해당 클래스 내부의 변수와 인풋 파라미터의 이름이 같으면 문제가 생긴다. 이럴 때는 this.를 통해 나는 내 클래스 안에 변수를 참조할거야! 해주면 된다.
public void deposit(int coinAmount) { // 클래스의 전역 변수명과 같은 지역 변수명을 인풋 파라미터로 사용하면 경우 문제가 된다.
this.coinAmount = this.coinAmount + coinAmount; // this.를 붙이면 괄호 밖 자기 자신의 클래스에 있는 변수로 접근한다.
// this.coinAmount 와 메소드 바깥의 coinAmount -> SaveBox 내의 변수
// 메소드 내의 coinAmount -> 인풋 파라미터
}
public void withdraw() {
System.out.println("모든 금액의 합계는 " + coinAmount + "입니다.");
}
// setter라 부름. 인풋.
public void setCoinAmount(int newAmount) {
coinAmount = newAmount;
}
// getter라 부름. 아웃풋.
public int getCoinAmount() {
return coinAmount;
}
// 왜 사용할까? setter getter라는 개념은 객체 내부의 데이터를 외부에서 접근 못하게 한다는 개념으로 인해 생겨났다.
// 데이터에 직접 접근하지 말고 메소드를 통해 접근하라는 뜻.
// 데이터가 2개면 setter getter도 2개씩(총 4개), 데이터가 3개면 setter getter도 3개씩(총 6개)
// 즉, coinAmount 하나니까 setter getter가 각 하나씩 2개지만, 다른 데이터가 하나 더 있다면 4개가 된다.
}
정리 1 )
일반적으로 클래스.메소드 로 메소드를 이용하지만 클래스.변수명 으로 변수에 직접 접근할 수도 있다.
이런 접근을 막기 위해서는 priviate으로 변수를 보호할 수 있다.
정리 2 )
위 1번의 경우를 금지하는 것이 자바 업계의 암묵적 룰이다. 따라서 해당 변수에 직접 접근을 원할 경우 변수로 접근하는게 아니고, 클래스 내에 setter라는 변수에 값을 넣는 인풋 메소드, getter 라는 변수의 값을 가져오는 아웃풋 메소드를 변수마다 만들어 사용한다. (메모리 비효율적....) setter, getter를 사용할 때는 반드시 private로 변수를 보호한다.
정리 3 )
일반적으로 메소드의 인풋 파라미터는 해당 클래스 내에 있는 변수명과 동일하게 사용하지 않는다.
동일하게 사용될 경우 해당 메소드 내에 있는 변수에 this.를 붙이게 되면 그 변수는 자기 클래스 내의 값을 참조하게 되어 인풋 파라미터와 구분할 수 있다.
'개발자 > Java' 카테고리의 다른 글
Java (자바) ATM 저금통, BMI (0) | 2020.04.10 |
---|---|
Java (자바) 예외처리 try catch (0) | 2020.04.09 |
Java (자바) 접근 제어자 (public, protected, default, private) (0) | 2020.04.07 |
Java (자바) 클래스와 메소드 만들기 (0) | 2020.04.07 |
Java (자바) 문자열 비교연산, 형변환을 이용한 종료 조건 구현 (0) | 2020.04.06 |