[김영한의 실전 자바 기본편] - 생성자

jkky98·2024년 4월 25일
0

Java

목록 보기
11/51

this

파이썬을 잘 안다면, 파이썬의 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은 적절한 것을 골라 생성자를 호출한다.

profile
자바집사의 거북이 수련법

0개의 댓글