[자바 기초] 11강. 태어날 때부터 완벽하게: 생성자(Constructor) 완벽 가이드
지난 시간 복습과 이번 강의 목표
지난 시간까지 우리는 학생 한 명을 만들기 위해 이렇게 코드를 짰습니다.
Student s1 = new Student(); // 1. 일단 껍데기만 생성
s1.setName("철수"); // 2. 이름 주입
s1.setScore(90); // 3. 점수 주입
코드가 3줄이나 필요합니다. 만약 깜빡하고 2번을 빼먹으면? 이름이 null인 유령 학생이 생깁니다.
"객체를 만들 때(new) 아예 이름과 점수를 필수로 받으면 안 될까?"
이것을 가능하게 하는 것이 바로 **생성자(Constructor)**입니다.
1. 생성자란 무엇인가?
생성자는 new 키워드를 쓸 때 딱 한 번 호출되는 특별한 메소드입니다.
주로 객체가 처음 생겨날 때 필요한 **초기 세팅(Initialization)**을 담당합니다.
생성자의 2가지 규칙
- 이름이 클래스 이름과 똑같아야 합니다. (
Student클래스의 생성자는Student여야 함) - 리턴 타입(void, int 등)이 아예 없습니다.
2. 생성자 만들기
Student.java 파일에 생성자를 추가해 봅시다.
이제 이 학생은 태어날 때 이름과 점수를 받지 않으면 태어날 수 없게 됩니다.
// Student.java
public class Student {
private String name;
private int score;
// 1. 생성자 정의 (Constructor)
// "나를 만들고 싶으면 이름과 점수를 가져와라!"
public Student(String name, int score) {
this.name = name; // 받아온 이름을 내 필드에 저장
this.score = score; // 받아온 점수를 내 필드에 저장
}
// (기존의 Getter, Setter는 그대로 둡니다)
public String getName() { return name; }
public int getScore() { return score; }
}
3. 확 바뀐 객체 생성 방식
이제 Main.java로 가서 코드를 보세요. 빨간 줄(에러)이 떴을 겁니다.
"기본 생성자(new Student())는 더 이상 사용할 수 없습니다."
이제 우리는 생성자가 정한 규칙대로 객체를 만들어야 합니다.
// Main.java
public class Main {
public static void main(String[] args) {
// 예전 방식: 에러 발생!
// Student s1 = new Student();
// 새로운 방식: 한 줄로 끝!
// "이름은 철수고, 점수는 90점인 학생을 만들어줘"
Student s1 = new Student("철수", 90);
Student s2 = new Student("영희", 85);
System.out.println(s1.getName() + "의 점수: " + s1.getScore());
System.out.println(s2.getName() + "의 점수: " + s2.getScore());
}
}
실행 결과
철수의 점수: 90
영희의 점수: 85
코드가 3줄에서 1줄로 줄었고, 이름이나 점수를 빼먹을 위험도 사라졌습니다. (안 넣으면 에러가 나니까요!)
4. 중요한 비밀: 기본 생성자 (Default Constructor)
"어? 예전에는 생성자를 안 만들었는데 왜 new Student()가 됐었죠?"
자바의 친절한 규칙 때문입니다. 개발자가 생성자를 하나도 안 만들면, 자바 컴파일러가 눈에 안 보이는 기본 생성자를 몰래 넣어줍니다.
// 우리가 안 만들어도 이게 있다고 칩니다.
public Student() {
// 아무 일도 안 함
}
🚨 주의: 하지만 우리가 Student(String name, int score) 같은 생성자를 하나라도 만드는 순간, 자바는 "아, 이제 네가 알아서 하는구나?" 하고 기본 생성자를 자동으로 만들어주지 않습니다.
그래서 아까 new Student()에서 에러가 났던 겁니다.
5. 생성자 오버로딩 (골라 먹는 재미)
"저는 이름만 알고 점수는 나중에 넣고 싶은데요?" 그럼 생성자를 여러 개 만들면 됩니다. 이것을 **오버로딩(Overloading)**이라고 합니다.
// Student.java 안에 추가
// 옵션 1: 이름과 점수 둘 다 받는 생성자
public Student(String name, int score) {
this.name = name;
this.score = score;
}
// 옵션 2: 이름만 받는 생성자 (점수는 0점으로 자동 세팅)
public Student(String name) {
this.name = name;
this.score = 0; // 혹은 this(name, 0); 으로 쓸 수도 있음 (심화)
}
이제 Main에서 입맛대로 골라서 객체를 만들 수 있습니다.
Student s1 = new Student("철수", 90); // 옵션 1 사용
Student s2 = new Student("민수"); // 옵션 2 사용
6. 마무리
이제 여러분은 객체를 안전하고 편리하게 생성하는 방법까지 마스터했습니다. 클래스(설계도) -> 필드(private) -> 메소드(Getter/Setter) -> 생성자(Constructor) 이 4단계가 바로 객체지향 프로그래밍의 기본 세트입니다.
그런데 개발을 하다 보면 이런 경우가 생깁니다. "학생 클래스랑 거의 똑같은데, '장학금' 기능만 추가된 '장학생' 클래스를 만들고 싶어." 처음부터 코드를 복사해서 다시 짜야 할까요?
다음 **[12강]**에서는 부모님의 재산(코드)을 그대로 물려받아 사용하는 **상속(Inheritance)**에 대해 배워보겠습니다. 코드 재사용의 끝판왕이 등장합니다.