[JAVA] 생성자 알아보기
생성자
김영한의 실전 자바 기본편을 보며 정리해보는 자바의 생성자 개념
생성자란?
객체를 생성하는 시점에 즉시 필요한 기능을 수행할 수 있게 하는 기능
생성자가 필요한 이유
객체를 생성하고 나면 변수에 초기값을 설정해주어야 한다.
객체를 생성할 때마다 이렇게 초기값을 설정하는 부분이 계속 반복되게 된다.
1
2
3
4
Member member1 = new Member();
member1.name = "user1";
member1.age = 15;
member1.grade = 90;
먼저 이런 부분을 메서드를 사용해 개선해 보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void main(String[] args) {
Member member1 = new Member();
initMember(member1, "user1", 15, 90);
Member member2 = new Member();
initMember(member2, "user2", 16, 80);
Member[] members = {member1, member2};
for (Member member : members) {
System.out.println("이름: " + member.name + "나이: " + member.age + " 성적: " + member.grade);
}
}
static void initMember(Member member, String name, int age, int grade) {
member.name = name;
member.age = age;
member.grade = grade;
}
initMember
메서드를 통해 참조형 변수 member
를 매개변수로 받아 해당 주소의 name
, age
, grade
의 값을 설정해줄 수 있게 되었다.
그러나 이 코드는 객체 지향 프로그래밍에 적합하지 않다.
객체 지향적인 코드는 데이터와 그 데이터에 대한 행동(메서드)이 하나의 객체 안에 포함되어 있어야 한다.
코드의 가독성과 이후 코드의 변경을 더 쉽게 관리하기 위해 Member
클래스에서 initMember
를 관리하도록 고쳐보자.
1
2
3
4
5
6
7
8
9
10
11
public class Member {
String name;
int age;
int grade;
void initMember(String name, int age, int grade) {
this.name = name;
this.age = age;
this.grade = grade;
}
}
이제 Member 인스턴스를 통해 initMember
메서드에 접근할 수 있게 되었다.
그런데 새로운 키워드가 눈에 보인다. this
는 뭘까?
❔ this
인스턴스 자신의 참조값을 가리키는 키워드
멤버 변수와 메서드의 매개변수 이름이 같은 경우 매개변수가 코드 블럭의 더 안쪽에 있기 때문에 우선순위를 가지게 된다. 따라서 initMember(String name, ...)
안에서 name
에 접근하면 매개변수 name
에 접근하게 된다.
멤버 변수에 접근하려면 앞에 this
키워드를 사용하면 된다.
여기서 this
는 인스턴스 자신의 참조값을 가리킨다.
이제 this.name
은 인스턴스 내부에 존재하는 멤버 변수를 가리키게 된다.
this
는 생략할 수도 있다.
생략하는 경우 가까운 지역변수(혹은 매개변수)를 먼저 찾고 없으면 그 다음으로 멤버 변수를 찾는다. 멤버 변수도 없다면 오류가 발생한다.
정리하면,
- 매개변수의 이름과 멤버 변수의 이름이 같은 경우
this
를 사용해서 둘을 명확하게 구분해야 한다. this
는 인스턴스 자신을 가리킨다.
생성자의 도입
객체를 생성하자마자 즉시 필요한 기능을 편리하게 수행할 수 있도록 제공
initMember
메서드와 같은 기능을 하기 위해 자바에서 제공해주는 기능이 생성자다.
객체를 생성하고 이후 바로 초기 값을 할당해야 하는 경우, 혹은 생성하자마자 어떤 기능을 수행해야 한다고 할 때 반복되는 코드를 줄이기 위해 생성자라는 기능이 제공된다.
생성자를 사용하면 객체를 생성하는 시점에 즉시 필요한 기능을 수행할 수 있다.
생성자는 메서드와 비슷하지만 다음과 같은 차이점이 있다.
- 생성자의 이름은 클래스의 이름과 같아야 한다.
- 반환 타입이 없다.
1
2
3
4
5
6
7
8
9
10
11
public class Member {
String name;
int age;
int grade;
Member(String name, int age, int grade) {
this.name = name;
this.age = age;
this.grade = grade;
}
}
생성자는 인스턴스를 생성하고 나서 즉시 호출된다.
다음과 같이 new
명령어 다음에 생성자 이름과 매개변수에 맞추어 인수를 전달하면 된다.
1
2
new 생성자이름(생성자에 맞는 인수 목록)
new 클래스이름(생성자에 맞는 인수 목록)
1
Member member1 = new Member("user1", 15, 90);
이렇게 하면 Member
인스턴스를 생성하는 즉시 해당 생성자가 호출되게 된다.
생성자의 장점
중복 호출 제거
생성자가 없을 때에는 생성 직후에 어떤 작업을 수행해야 할 때 메서드를 직접 한번 더 호출해야 했다.
생성자 덕분에 이런 작업을 줄이고 객체를 생성하면서 동시에 필요한 작업을 수행할 수 있게 되었다.
생성자 호출이 필수적이도록 제약
필수 값 입력을 보장
객체가 반드시 데이터를 가지고 있어야 하는 경우, 깜빡하고 데이터를 입력해주지 않았다면 시스템에 큰 문제를 초래할 수 있다.
생성자는 객체를 생성할 때 직접 정의한 생성자가 있다면 반드시 호출하도록 강제하고 있다. 호출하지 않으면 컴파일 오류를 발생시킨다.
이 경우 개발자는 객체를 생성할 때 직접 정의한 생성자를 필수로 호출해야 한다는 것을 바로 알 수 있으므로 필수 값 입력을 보장한다.
기본 생성자
매개변수가 없는 생성자
1
ArrayList<String> list = new ArrayList<>()
자바를 사용하다보면 다음과 같이 객체를 생성할 때 ()
를 포함하는 경우를 많이 보았을 것이다.
이 때 ()
를 사용해야 하는 이유도 생성자 때문이다.
객체를 생성하면서 동시에 빈 생성자를 호출한다는 의미를 포함하는 것이다.
클래스에 생성자가 하나도 없으면 자바 컴파일러는 매개변수가 없고, 작동하는 코드가 없는 기본 생성자는 자동으로 만들어 준다.
만약 자바에서 기본 생성자를 만들어주지 않는다면 생성자 기능이 필요하지 않은 경우에도 모든 클래스에 개발자가 직접 기본 생성자를 정의해야 한다.
생성자 기능을 사용하지 않는 경우도 많기 때문에 이런 편의 기능을 제공한다.
생성자가 하나라도 있으면 기본 생성자를 만들지 않는다.
정리 해보면,
- 생성자는 반드시 호출되어야 한다.
- 생성자가 없으면 자동으로 빈 생성자가 생성된다.
- 생성자가 하나라도 있으면 기본 생성자가 제공되지 않는다.
- 개발자가 정의한 생성자를 직접 호출해야 한다.
생성자 오버로딩과 this()
생성자를 오버로딩하면 상황에 맞게 필요한 부분만 입력받아 사용할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Member {
String name;
int age;
int grade;
Member(String name, int age) {
this(name, age, 50);
}
Member(String name, int age, int grade) {
this.name = name;
this.age = age;
this.grade = grade;
}
}
생성자는 여러 개의 매개 변수를 입력받을 수 있도록 오버로딩 할 수 있다.
이 때, this()
를 사용하면 자기 자신의 생성자를 호출할 수 있다.
1
2
3
4
5
6
Member(String name, int age) {
this(name, age, 50);
// this.name = name;
// this.age = age;
// this.grade = 50;
}
이렇게 하면 같은 실행 결과지만 코드의 중복을 제거할 수 있다.
⚠️ 단, this()
는 생성자 코드의 첫줄에만 작성할 수 있다.
정리
- 생성자는 객체를 생성하는 시점에 즉시 필요한 기능을 수행함
- 코드의 중복을 줄이고, 필수 값 입력을 보장하는 장점을 가짐
- 객체를 생성할 때 반드시 호출되어야 함
- 생성자가 존재하지 않는 클래스의 경우 자바에서 기본 생성자를 만들어 줌
this
는 인스턴스 자신을 가리킴 -> 인스턴스 멤버 변수 호출이나 생성자 호출 시 사용