나의 IT일지
생성자 본문
클래스를 통해 객체를 생성할 때, new연산자를 통해 힙 영역에 객체를 생성하고, 해당 객체의 주소를 참조변수에 저장을 한다.
클래스명 참조변수 = new 클래스명();
이때 new 클래스명()에서 new연산자는 객체를 생성하는 역할을 한다. 그렇다면 "클래스명()"는 무슨 역할을 하는 것일까?
생성자
"클래스명( )"은 객체의 초기값을 하는 생성자이다. 생성자란 객체 생성시 초기화를 담당하는 역할로, new연산자를 통해 생성자의 블록의 내용를 호출한다. 즉, 생성자의 블록에 값을 저장하는 명령어가 있을 경우, 해당 값으로 변수를 초기화하며, 메서드가 있을경우, 객체를 사용하기 전에 메서드를 호출한다.
기본 생성자
모든 클래스는 생성자가 반드시 필요하다. 하지만 클래스를 선언할 때 생략을 하는 경우가 있는데, 이럴 경우에는 생성자가 자동적으로 생성되며, 생성되는 생성자를 기본생성자라고 한다. 기본생성자란 생성자 블록의 내용이 비어있는 생성자로, 블록이 비어있기 때문에, 객체의 변수들은 기본값으로 초기화가 된다.
클래스 명( ) { } |
이때, 생성자는 클래스명과 동일한 것을 확인할 수 있으며, 생성자는 메서드와 비슷한 모양을 가지고 있지만 리턴타입이 없는 것을 확인할 수 있다.
package pack0413;
public class Code1 {
public static void main(String[] args) {
ClassA a = new ClassA();
System.out.println(a);
}
}
class ClassA{
int a;
char b;
}
생성자의 구조
기본 생성자 대신 생성자를 클래스 안에 직접 선언해서, 생성자를 생성할 수 있으며, 형태는 다음과 같은 형태로 작성하면 된다.
클래스명(매개변수,...){ 클래스의 변수 = 매개변수; ... 메서드; ... } |
위의 구조는 생성자를 생성하는 구조로, 매개변수 없이 선언할 수 있으며, 매개변수를 선언했을 경우에는 new연산자로 생성자를 호출할 때 같이 선언하면 된다. 이때 매개변수란 값을 메서드나 생성자 블록 내부에 전달하는 변수이다.
package pack0413;
public class Code2 {
public static void main(String[] args) {
Phone myphone1=new Phone();
Phone myphone2=new Phone("iphone","white",64);
myphone1.model="Galaxy";
myphone1.color="black";
myphone1.capacity=64;
myphone1.info();
myphone2.info();
}
}
class Phone{
String model;
String color;
int capacity;
Phone(){
System.out.println("핸드폰 생성");
}
Phone(String model,String color){
this.model=model;
this.color=color;
this.capacity=64;
System.out.println("핸드폰 생성");
}
Phone(String model,String color,int capacity){
this.model=model;
this.color=color;
this.capacity=capacity;
System.out.println("핸드폰 생성");
}
void info() {
System.out.println("model:"+model);
System.out.println("color:"+color);
System.out.println("capacity:"+capacity);
}
}
위의 소스코드를 보면, 생성자를 선언할 때, 매개변수를 사용하지 않는 생성자와 매개변수를 사용하는 생성자가 있다. 즉, 생성자를 선언할 때, 클래스명을 동일하게 사용하지만 매개변수의 갯수가 다른 것을 확인할 수 있다. 이를 생성자 오버로딩이라고 하는데, 여러 개의 생성자를 생성할 때 매개변수의 갯수나 순서가 다를 경우에 서로 다른 생성자로 인식되는 것을 말한다.
매개변수를 사용하지 않고 블록에 내용을 추가한 생성자를 사용하는 경우에는 객체를 생성할 때 매개변수가 없기에 매개변수에 값을 추가하지 않으며, 실행할 경우 블록에 있는 "System.out.println("핸드폰 생성");"가 실행되는 것을 확인할 수 있다.
매개변수를 사용하면서, 블록에 내용을 추가한 생성자를 사용하는 경우, 객체를 생성할 때 매개변수에 값을 추가해야 하며, 매개변수에 따라 블록에 있는 클래스의 변수에 매개변수의 값을 저장되며, 블록에 있는 "System.out.println("핸드폰 생성");"가 실행되는 것을 확인할 수 있다.
이때 생성자의 블록을 보면, "this"키워드가 있는데, "this"키워드는 생성자나 메서드가 클래스의 변수를 사용하기 위해서 사용하는 것으로, 매개변수의 변수명과 클래스의 변수의 이름이 같을 경우에 this키워드를 이용하여 구분한다.
정리하면 다음과 같이 설명할 수 있다.
- 매개변수가 있는 생성자는 객체 생성할 때, 매개변수의 타입에 따라 값을 추가해야 한다.
- 매개변수가 없는 생성자는 객체 생성할 때, 매개변수 입력칸에 아무것도 입력하면 안된다.
- 객체가 생성할 때, 매개변수가 있든없든 블록안에 있는 명령은 수행된다.
객체의 초기화
클래스로부터 객체가 생성할 때, 생성자에 따라 자동적으로 기본값으로 초기화가 된다. 하지만 클래스안에 있는 변수에 초기값을 주게 되면, 동일한 클래스로 생성되는 객체는 해당 값으로 초기화하게 된다.
즉, 객체 생성할 때, 생성자에게 매개변수를 입력하지 않거나, 객체 생성 후 값을 저장하지 않는 이상, 해당 변수의 값은 초기값으로 모두 동일하게 된다.
package pack0413;
public class Code1 {
public static void main(String[] args) {
ClassA a = new ClassA();
ClassA b = new ClassA();
ClassA c = new ClassA(20);
System.out.println("a.a="+a.a);
System.out.println("b.a="+b.a);
System.out.println("c.a="+c.a);
}
}
class ClassA{
int a= 10;
ClassA(){}
ClassA(int a){
this.a = a;
}
}
this( ) 메서드
생성자를 매개변수의 수만 달리하고 블록의 초기화 내용이 비슷하게 만드는 생성자 오버로딩 할 때, 생성자 간의 중복된 코드가 발생하게 된다.
class Phone{
String model;
String color;
int capacity;
Phone(String model,String color){
this.model=model;
this.color=color;
this.capacity=64;
System.out.println("핸드폰 생성");
}
Phone(String model,String color,int capacity){
this.model=model;
this.color=color;
this.capacity=capacity;
System.out.println("핸드폰 생성");
}
void info() {
System.out.println("model:"+model);
System.out.println("color:"+color);
System.out.println("capacity:"+capacity);
}
}
이럴 경우, 블록 초기화 내용은 한 생성자에만 집중적으로 작성하고 나머지 생성자에는 초기화 내용을 가지고 있는 생성자를 호출하여 사용하는데, 이럴때 사용하는 메서드가 this()메서드이다.
this()메서드는 클래스 내의 생성자의 내용을 호출하는 메서드로, 매개변수의 형태에 따라서 호출하는 생성자가 결정되며, 값을 작성하면 호출하는 생성자의 매개변수에 해당 값이 저장되어서 호출이 된다. 이때, this()메서드는 생성자의 첫 줄에 사용해야 한다.
this(생성자의 매개값1, 생성자의 매개값2 ...)
class Phone{
String model;
String color;
int capacity;
Phone(String model,String color,int capacity){
this.model=model;
this.color=color;
this.capacity=capacity;
System.out.println("핸드폰 생성");
}
Phone(String model,String color){
this(model,color,64);
System.out.println("핸드폰 생성");
}
void info() {
System.out.println("model:"+model);
System.out.println("color:"+color);
System.out.println("capacity:"+capacity);
}
}
위의 두 phone클래스의 코드는 같은 코드이며, "this(model,color,64);"를 통해 "Phone(String model,String color,int capacity)" 생성자에서 "capacity"의 값은 64로 고정되어서 호출이 된다.