생성자는 무엇이며 어떻게 사용될까?
생성자 (Constructor)
--
생성자는
객체를 생성할 때 호출되는 특별한 메서드를 의미한다.
(객체 생성과 동시에 호출되는 메서드)
주로 객체가 생성될 때 필드(인스턴스 변수)를 초기화하거나,
객체를 초기 상태로 설정하는 데 사용된다.
생성자 규칙
- 생성자의 이름은 해당 클래스의 이름과 동일해야 한다.
- 생성자는 반환 타입이 없으며 return 값 또한 없다. (void 자체도 사용하지 않는다.)
- 객체가 생성될 때 자동으로 호출된다.
- 생성자 또한 오버로딩이 가능하다. (하나의 클래스에 여러 개의 생성자 정의 가능)
예시 코드
class Card {
String name;
int age;
Card() { // 매개변수가 없는 생성자 (기본 생성자)
name = "nijy";
age = "20";
}
Card(String str, int num) { // 매개변수가 있는 생성자
name = str;
age = num;
}
}
Card ccc1 = new Card(); // 객체 생성과 동시에 Card() 생성자 호출(실행)
Card ccc2 = new Card("mark", 38); // 겍체 생성과 동시에 Card(String str, int num) 생성자 호출 (실행)
생성자를 통해 객체 생성 과정
클래스명 객체명 = new 생성자;
객체를 생성할 때, 위와 같은 형식으로 객체를 생성한다.
클래스명 객체명; // 메모리에 할당하지 않고 그냥 참조 변수를 선언만 수행한 상태
위 코드는 그냥 참조 변수를 선언만 수행한 상태로 참조하는 값(주소)이 없어 null값을 가진 상태로
스택 메모리에 할당된다.
(어떻게 보면 그냥 null값을 가진 변수일뿐인 상태다.)
객체명 = new 생성자;
"new" 키워드는
(이때 만약 특별한 초기화 작업이 없으면 필드들은 기본값으로 자동 초기화된다.)
JVM에게 힙 메모리에 해당 객체를 위한 공간을 할당하라는 명령어다.
(할당된 공간에는 해당 클래스의 필드들이 담겨 있다.)
그러고 나서 생성자를 호출하여 수행하게 된다.
(힙 메모리에 담긴 필드들을 초기화해 주거나, 다른 동작 수행)
그리고 나서 해당 힙 메모리의 주소를 참조 변수에 저장하여
비로소 객체가 생성되는 것이다.
참조 변수는 스택 메모리에 할당되어 있으며,
값은 실질적인 데이터가 담긴 힙 메모리의 주소를 가리키고 있는 구조다.
왜 객체를 생성할 때 생성자를 꼭 호출해야 하는가?
- 객체 초기화 보장
- 객체가 필요한 자원을 할당
객체를 생성할 때는 그 객체가 사용할 준비가 되어 있어야 한다.
즉, 객체의 필드들이 적절하게 초기화된 상태여야만, 해당 객체를 올바르게 동작할 수 있게 된다.
그래서 만약 초기화를 빼먹어 올바른 동작을 수행하지 못하는 것을 방지하기 위해
꼭 생성자를 거쳐 객체를 생성하도록 구성한 것이다.
(+ 객체의 일관성 유지하기 위해)
생성자는 필드 초기화 외에도, "파일 핸들링", "DB 연결", "네트워크 소켓 생성" 등
객체가 사용할 외부 자원을 할당하는 역할도 할 수 있다. (직접 해당 로직을 생성자에 작성해야 함)
생성자 종류
- 매개변수가 없는 생성자 ("기본 생성자"라고 부른다.)
- 매개변수가 있는 생성자
--
기본 생성자 (Default Constructor)
--
기본 생성자는
매개변수가 없는 생성자를 말하며, 생략할 수 있다.
만약 클래스에 생성자가 하나도 없는 경우 컴파일러가 자동으로 기본 생성자를 추가해 주므로
클래스에는 적어도 하나 이상의 생성자가 있도록 보장하며
해당 생성자를 통해 객체를 생성할 수 있도록 한다.
자동으로 생성된 기본 생성자는 아무런 내용이 존재하지 않는다.
class Card {
// Card() { } // 자동으로 추가된 기본 생성자
}
그래서 클래스에 생성자를 정의하지 않아도
자동으로 추가된 기본 생성자를 통해 객체를 생성할 수 있는 것이다.
예시 코드
class Data1 { // 생성자가 없어 기본 생성자 자동 생성
int a;
// Data1() { }
}
class Data2 { // 생성자가 존재하여 기본 생성자 자동 생성 안함
int a;
Data2(int x) {
a = x;
}
}
Data1 d1 = new Data1(); //매개변수 없는 생성자(기본 생성자) 호출
Data2 d2 = new Data2(); //에러!! 매개변수 없는 생성자(기본 생성자)가 없다.
Data2 d2 = new Data2(10); //가능
--
this, this() (+ 생성자에서 다른 생성자 호출하기)
--
this는
현재 위치하는 클래스명을 대신하여 사용하는 키워드로
this = 현재 클래스명이라고 생각하면 된다.
this()는
현재 위치하는 클래스의 생성자를 대신하여 사용하는 키워드로
this() = 생성자라고 생각하면 된다.
생성자에서 다른 생성자를 호출하는 경우
반드시 첫 줄에서만 호출이 가능하다.
예시 코드
class Car {
String color;
String gearType;
int door;
Car() {
this("white", "auto", 4); // 다른 생성자(Car(String color, String gearType, int door)) 호출
}
Car(String color) {
this(color, "auto", 4); // 다른 생성자(Car(String color, String gearType, int door)) 호출
}
Car(String color, String gearType, int door) {
this.color = color; //this.color는 클래스 Car의 멤버변수(Car.color)
this.gearType = gearType; //color는 매개변수 Color를 의미
this.door = door;
}
/*
매개변수와 멤버변수의 이름이 다를 때
Car(String c, String g, int d) {
color = c; //color는 클래스 Car의 멤버변수 color
gearType = g; //c는 매개변수 c를 의미
door = d;
}
*/
}
this 키워드는 보통
멤버변수와 매개변수의 이름이 같아 구분을 짓기 위해 사용한다.
만약 이름이 다르다면 굳이 this 키워드를 사용하지 않아도 된다. (사용은 가능)
하지만 되도록 이름을 같게 하고 this 키워드를 사용하는 것이 보기 편하다.
--
'Language > Java' 카테고리의 다른 글
상속 (+ super, super(), 포함 관계) (0) | 2024.10.17 |
---|---|
오버로딩, 오버라이딩 (0) | 2024.10.16 |
클래스, 객체, 인스턴스 (+ 객체 생성 방법) (2) | 2024.10.12 |
배열(Arrays 클래스) 관련 메서드 정리 (0) | 2024.10.11 |
배열 (+ 다차원 배열) (0) | 2024.10.10 |