이번 편의 목표: 생성자에서 값을 검사하고, private 필드는 메서드로만 읽게 합니다.

객체를 만든 뒤에 필드를 하나씩 넣으면, 제목이 비어 있거나 연체 일수가 음수인 상태가 잠깐 존재합니다. 생성자는 객체가 만들어질 때 한 번 실행되는 초기화 코드입니다.

생성자와 getter

이제부터 뒤 편의 Book은 이 모양을 기준으로 합니다. 파일 이름은 Book.java입니다.

Java
public class Book {
    private final String title;
    private final int lateDays;

    public Book(String title, int lateDays) {
        if (title == null || title.isBlank()) {
            throw new IllegalArgumentException("제목이 필요합니다.");
        }
        if (lateDays < 0) {
            throw new IllegalArgumentException("연체 일수는 0 이상이어야 합니다.");
        }
        this.title = title.trim();
        this.lateDays = lateDays;
    }

    public String getTitle() {
        return title;
    }

    public int getLateDays() {
        return lateDays;
    }

    public int lateFee() {
        return lateDays * 100;
    }
}

private 필드는 클래스 밖에서 직접 읽을 수 없습니다. getTitle과 getLateDays로만 읽습니다. final은 생성자 이후 그 필드를 다시 대입하지 않겠다는 표시입니다. this.title은 매개변수 title과 필드 title을 구분합니다.

비어 있는 제목으로 new Book(" ", 1)을 호출하면 객체가 만들어지지 않고 IllegalArgumentException이 발생합니다. 잘못된 책을 목록에 넣은 뒤 고치는 방식보다, 만들 때 거절하는 방식이 뒤 계산을 단순하게 만듭니다.

실행용 main은 다른 클래스에 두거나, 학습 중에는 public을 붙이지 않은 클래스로 시험할 수 있습니다. 아래는 사용 예입니다.

Java
Book book = new Book("개미", 3);
System.out.println(book.getTitle());
System.out.println(book.lateFee());

출력은 개미와 300입니다.

직접 해 보기

제목과 연체 일수를 받는 생성자를 유지한 채, 연체료를 출력하는 describe 메서드를 추가하세요. 개미, 3일이면 개미: 300원 형식입니다.

해설

Java
public String describe() {
    return getTitle() + ": " + lateFee() + "원";
}

describe는 클래스 안에서는 private 필드를 직접 읽어도 됩니다. getter와 lateFee를 사용하면 출력 형식이 계산 규칙을 다시 적지 않습니다.