파이썬을 잘 안다면, 파이썬의 self와 대응되는 기능이다. this는 self처럼 인스턴스 자신을 가르킨다.
package class1.ex;
public class Account {
int balance = 0;
void deposit(int amount) {
balance += amount;
status();
}
void withdraw(int amount) {
if (amount > balance) {
System.out.println("출금 불가");
status();
} else {
int money = balance - amount;
balance -= amount;
System.out.println("출금 했습니다. : " + money);
status();
}
}
void status() {
System.out.println("현재 잔액 : " + balance);
}
}
위의 코드에서 만약 멤버변수 balance가 money이고 deposit, withdraw 메소드의 입력또한 money이면 어떻게 될까?
money += money;, money -= money;와 같은 코드들이 생겨날 것이다. 같은 변수명일 경우 자바는 우선순위로 현재의 코드블럭에서 쓰인 money를 money에 반영한다. 만약 현재 코드블럭에 없다면 그 다음은 멤버변수의 money로 매핑될 것이다.
이 논리대로라면 money += money;
는 같은것에 같은것을 부여하는 꼴이 된다.
멤버변수 money
에 인자 money
를 +=로 연산을 적용하기 위해 멤버변수 money
를 표현할 문법이 필요하다. 그러므로 멤버변수를 지정할 수 있는 this.money란 표현이 이해가 된다. 이를 반영해서 다음과 같이 this.money += money
로 작성해야한다.
package class1.ex;
public class Account {
int money = 0;
void deposit(int money) {
this.money += money;
status();
}
void withdraw(int money) {
if (money > this.money) {
System.out.println("출금 불가");
status();
} else {
this.money -= money;
System.out.println("출금 했습니다. 출금액: " + money);
status();
}
}
void status() {
System.out.println("현재 잔액 : " + this.money);
}
}
만약 인자와 멤버변수의 이름이 같지 않다면 당연히 this는 생략할 수 있다.
이전에 멤버변수를 일일이 할당 하지 않고 initAccount()와 같은 static 메서드를 만들어 클래스 안의 멤버변수에 자동 초기화된 값을 수정한 기억이 있다. 생성자 방식을 쓰면 메서드를 사용하지 않고. Account ac1 = new Account(name, money, stock)
와 같이 바로 객체 생성시 멤버변수 초기화가 가능하다.
package class1.ex;
public class Account {
int balance;
Account(int balance) {
this.balance = balance;
}
void deposit(int amount) {
balance += amount;
status();
}
void withdraw(int amount) {
if (amount > balance) {
System.out.println("출금 불가");
status();
} else {
int money = balance - amount;
balance -= amount;
System.out.println("출금 했습니다. : " + money);
status();
}
}
void status() {
System.out.println("현재 잔액 : " + balance);
}
}
생성자를 만드는 방식에 익숙해지자.
일반적인 메서드와는 다르다. 일단 같은 클래스명이 들어가며 void와 같은 선언이 필요하지 않다. 클래스를 생성할 때 바로 괄호 안에 데이터를 입력해 넣어 초기값 구성이 가능해진다. 파이썬의 def __init__(self, v1, v2)
과 비슷하다.
이러한 생성자 코드는 생성자 파라미터 사용을 강제하므로 생성자에 인자를 전달해서 사용하지 않았을 경우 컴파일 에러를 발생시켜 초기값이 없는 클래스가 만들어지지 않도록 할 수 있다.
만약 생성자를 선언하지 않았다면 자바는 매개변수가 존재하지 않는 기본 생성자를 자동으로 만든다. 그렇기에 우리가 생성자를 만들지 않은 클래스에 대해서
Account ac1 = new Account();와 같은 객체 생성 코드가 문제없이 수행될 수 있다. 그러나 자바는 매개변수가 하나라도 존재하는 생성자를 클래스안에 구성했다면 기본생성자를 만들지 않는다.
public class Account {
int balance;
String name;
Account(String name) {
this(50, name);
}
Account(int balance, String name) {
this.balance = balance;
this.name = name;
}
위와 같이 생성자를 두 개 선언하고, Account ac1 = new Account("Poul")
으로 객체를 생성하면 첫번째 생성자를 호출하며, Account ac1 = new Account("Poul", 80)
으로 객체를 생성하면 두번째 생성자를 호출한다.
이렇게 여러개의 생성자를 선언할 수 있으며 타입과 파라미터의 수에 따라 JVM은 적절한 것을 골라 생성자를 호출한다.