Dev.Std
생성자 (Constructor) 본문
생성자가 필요한 이유
Student 클래스를 생성 후, Student 객체마다 이름을 저장할 수 있도록 name이라는 인스턴스 변수를 선언하고, setName, getName 메서드를 이용해서 이름을 지정 및 반환하도록 하였다.
public class Student {
// 이름을 저장하는 인스턴스 변수
private String name;
// 이름 설정 메서드
public void setName(String name) {
this.name = name;
}
// 이름 반환 메서드
public String getName() {
return name;
}
}
그리고 아래에는 해당 클래스를 이용해서 새로운 Student 객체를 생성하고 이름을 설정하고, 설 정한 이름을 출력하는 예제를 만들었다.
public class Constructor {
public static void main(String[] args) {
// 학생 객체 생성
Student student = new Student();
// 이름 설정
student.setName("John");
// 이름 출력
System.out.println("Student name : " + student.getName());
}
}
Student name : John
위에 코드를 봤을 때는 간단하고 별 문제가 없어 보이는 코드인 것 같다. 그런데 Student 객체에는 name 이외에도 많은 인스턴스 변수가 존재할 수 있고, 또 일반적인 학교를 생각해 봤을 때 학생이 한 두 명이 아닌 수백에서 많게는 수천도 된다.
그래서 클래스에 학생의 나이(age)와 전공(major) 인스턴스 변수를 정의하고, main함수에서 학생 인스턴스를 조금 더 생성해 보았다.
public class Student {
private String name; // 이름을 저장하는 인스턴스 변수
private int age; // 나이를 저장하는 인스턴스 변수
private String major; // 전공을 저장하는 인스턴스 변수
// 이름 설정 메서드
public void setName(String name) {
this.name = name;
}
// 나이 설정 메서드
public void setAge(int age) {
this.age = age;
}
// 전공 설정 메서드
public void setMajor(String major) {
this.major = major;
}
// 이름 반환 메서드
public String getName() {
return name;
}
// 나이 반환 메서드
public int getAge() {
return age;
}
// 전공 반환 메서드
public String getMajor() {
return major;
}
}
public class Constructor {
public static void main(String[] args) {
// 학생1 객체 생성
Student student1 = new Student();
// 속성 설정
student1.setName("John");
student1.setAge(20);
student1.setMajor("Computer Science");
// 학생2 객체 생성
Student student2 = new Student();
// 속성 설정
student2.setName("Alice");
student2.setAge(22);
student2.setMajor("Mathematics");
// 학생이 수 백명 더 있다면
// 인스턴스 변수를 각각 하나씩 다 정의 해줄 것인가..?
// 학생 정보 출력
System.out.println("Student 1 - Name: " + student1.getName() + ", Age: " + student1.getAge() + ", Major: " + student1.getMajor());
System.out.println("Student 2 - Name: " + student2.getName() + ", Age: " + student2.getAge() + ", Major: " + student2.getMajor());
}
}
Student 1 - Name: John, Age: 20, Major: Computer Science
Student 2 - Name: Alice, Age: 22, Major: Mathematics
위의 코드를 살펴보면 학생 인스턴스를 2개만 생성했음에도 코드가 많이 길어졌다. 그런데 학생 인스턴스를 백 명, 많게는 천 명까지 생성해야 한다면 코드가 너무 복잡해질 것이다.
학생 인스턴스를 생성할 때 기본적인 정보들을 따로 정의하는 것이 아니라 동시에 정의할 수 있는 방법이 바로 생성자에 대한 부분이다.
생성자란?
생성자란 편하게 인스턴스가 생성될 때 호출되는 "인스턴스 초기화 메서드"라고 생각하면 될 것 같다. 다음은 위 코드에 생성자를 정의한 코드이다.
public class Student {
private String name; // 이름을 저장하는 인스턴스 변수
private int age; // 나이를 저장하는 인스턴스 변수
private String major; // 전공을 저장하는 인스턴스 변수
// 생성자
public Student(String name, int age, String major) {
this.name = name;
this.age = age;
this.major = major;
}
// 아래는 동일한 코드
// ...
코드를 살펴보면 초기화할 변수를 this 키워드를 이용해 매개 변수로 받은 값을 할당하고 있다.
public class Constructor {
public static void main(String[] args) {
// 학생1 객체 생성 (생성자 사용)
Student student1 = new Student("John", 20, "Computer Science");
// 학생2 객체 생성
Student student2 = new Student("Alice", 22, "Mathematics");
// 학생 정보 출력
System.out.println("Student 1 - Name: " + student1.getName() + ", Age: " + student1.getAge() + ", Major: " + student1.getMajor());
System.out.println("Student 2 - Name: " + student2.getName() + ", Age: " + student2.getAge() + ", Major: " + student2.getMajor());
}
}
Student 1 - Name: John, Age: 20, Major: Computer Science
Student 2 - Name: Alice, Age: 22, Major: Mathematics
setName, setAge, setMajor 메서드를 이용해서 인스턴스 변수를 따로 정의해 주던 번거로움은 사라지고, 객체를 생성함과 동시에 매개변수로 값을 넘겨주면서 각 객체의 인스턴스 변수에 대해 정의해주어 코드가 훨씬 간결해짐을 볼 수 있다.
생성자를 명시적으로 정의하지 않았다고 해서 생성자가 호출이 되지 않는 것이 아니다. 생성자가 사용자에 의해서 정의되지 않는 경우 컴파일러는 자동으로 기본 생성자(default constructor)를 호출하게 된다. 기본 생성자의 형태는 다음 코드에서 나타난다.
public class Student {
private String name; // 이름을 저장하는 인스턴스 변수
private int age; // 나이를 저장하는 인스턴스 변수
private String major; // 전공을 저장하는 인스턴스 변수
// 기본 생성자 (default constructor)
public Student() {
System.out.println("기본 생성자 호출!");
this.name = "Unknown";
this.age = 0;
this.major = "Unknown";
}
// 생성자
public Student(String name, int age, String major) {
this.name = name;
this.age = age;
this.major = major;
}
// 아래는 동일한 코드
// ...
public class Constructor {
public static void main(String[] args) {
// 기본 생성자를 사용하여 객체 생성
Student student = new Student();
System.out.println("Student - Name: " + student.getName() + ", Age: " + student.getAge() + ", Major: " + student.getMajor());
}
}
기본 생성자 호출!
Student - Name: Unknown, Age: 0, Major: Unknown
코드를 살펴보면 객체를 생성할 때 매개 변수를 아무것도 넣지 않았지만 기본 생성자가 호출되어 Name, Age, Major 변수에 값이 할당되는 것을 알 수 있다. 이렇듯 사용자 정의 생성자를 만들지 않았다면 암묵적으로 컴파일러가 기본 생성자를 호출하게 된다.
생성자의 특징
생성자는 크게 다음과 같은 특징이 있다.
- 객체 초기화 : 객체가 생성될 때 호출되며, 주로 객체의 초기화를 수행.
- 메서드 형태 : 일반적인 메서드와 동일한 형태, 반환 타입을 지정하지 않으며 클래스와 동일한 이름을 가짐.
- 오버로딩 : 하나의 클래스에 여러 생성자를 정의 (매개변수의 타입과 개수를 달리하여), 다양한 초기화 방법 지원.
- 명시적 및 암시적 호출 : 객체 생성 시 new 키워드와 함께 명식적으로 호출 가능. 생성자가 명시적으로 정의되지 않은 경우 컴파일러가 자동으로 기본 생성자(default constructor)를 추가.
'📂Language > Java' 카테고리의 다른 글
상속 (Inheritance) (0) | 2024.04.10 |
---|---|
접근 제어자 (Access Modifier) (0) | 2024.04.07 |
값에 의한 호출 & 객체(참조)에 의한 호출 (Call by value & Call by object(reference)) (0) | 2024.04.07 |
클래스 (Class) (0) | 2024.04.03 |