프로그래밍 언어/자바

자바 15. 생성자(Constructor)

닉네임못짓는사람 2020. 8. 28. 16:09
반응형

이번 글에서는 생성자에 대해서 알아보도록 하겠습니다.

생성자(Constructor)란?

생서자는 인스턴스가 생성될 때 호출되는 '인스턴스 초기화 메서드' 입니다.

따라서 인스턴스 변수의 초기화 작업등 인스턴스 생성 시에 실행되어야 하는 작업을 위해 사용됩니다.

 

생성자도 메서드처럼 클래스 내에 선언되며, 구조도 유사하지만 리턴값이 없습니다.

생성자의 조건은 다음과 같습니다.

1. 생성자의 이름은 클래스의 이름과 같아야 한다.

2. 생성자는 리턴값이 없다.

다음으로 생성자를 정의하는 방법입니다.

    클래스이름(타입, 변수명, 타입 변수명, ...){
        //인스턴스 생성 시 수행될 코드
    }
    Tv(){
        //매개변수가 없는 생성자
    }
    Tv(int height, int width){
        //매개변수가 있는 생성자
    }

이 생성자는 클래스의 인스턴스를 생성할 때, 즉 new Tv()부분에서 실행됩니다.

또한 생성자는 몇 가지 특징을 제외하면 기본적으로 메서드와 다르지 않으며, 오버로딩도 동일하게 가능합니다.

기본 생성자(default constructor)

사실 모든 클래스에는 반드시 하나 이상의 생성자가 정의되어 있어야 합니다.

그런데 우리는 지금까지 클래스를 사용하면서 따로 생성자를 정의한 적이 없지만, 문제없이 사용해왔습니다.

이게 가능한 이유는 컴파일러가 기본적으로 '기본 생성자(default constructor)를 제공하기 때문입니다.

 

컴파일 시 클래스에 생성자가 하나도 정의되어 있지 않은 경우 컴파일러가 자동적으로 다음과 같은 기본 생성자를 추가해서 컴파일합니다.

클래스이름(){}
Tv(){}

이 기본 생성자는 매개 변수도, 내용도 없이 텅텅 비어있습니다.

당연하게도 생성자가 클래스 내에 하나라도 정의되어 있으면, 이 기본 생성자는 추가되지 않습니다.

public class example{
    public static void main(String[] args){
        Tv t1 = new Tv();
    }
}

class Tv{
    Tv(int a){

    }
}

때문에 위와 같이 매개변수를 받는 생성자를 정의해놓고, 기본 생성자로 인스턴스를 생성하려고 하면 오류가 발생합니다.

이런 부분에 주의해서 생성자를 사용하시면 되겠습니다.

예제를 통해 생성자를 직접 정의해서 인스턴스를 생성해보도록 합시다.

public class example{
    public static void main(String[] args){
        Tv t1 = new Tv(1920, 1080);
        t1.tvSize();
    }
}

class Tv{
    int height;
    int width;

    Tv(int w, int h){
        width = w;
        height = h;
    }
    
    void tvSize(){
        System.out.println("width = " + width + ", height = " + height);
    }
}

이렇게 생성자를 정의해서 인스턴스 생성시에 인스턴스 변수의 값을 자신이 원하는 값으로 초기화할 수 있습니다.

생성자에서 다른 생성자 호출 - this(), this


같은 클래스의 멤버들 간에 서로 호출이 가능한 것처럼 생성자 간에도 다음의 두 가지 조건을 만족하면 호출이 가능합니다.

1. 생성자의 이름으로 클래스이름 대신 this를 사용한다.

2. 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출이 가능하다.

사용 방법은 다음과 같습니다.

Tv(){
	this(1920, 1080);
}
Tv(int w, int h){
	width = w;
	height = h;
}

위와 같이 사용하면 매개변수가 없는 생성자에서 매개변수가 있는 생성자를 호출할 수 있습니다.

또한 이 this는 변수나 메서드 앞에도 사용할 수 있습니다.  예를 들어 아래와 같은 경우가 있다고 생각해봅시다.

Tv(int width, int height){
        width = width;
        height = height;
}

이렇게 인스턴스 변수의 변수명과 매개변수의 변수명이 같으면 값을 대입할 수가 없습니다.

물론 이렇게 변수명이 안 겹치게 하는 것이 가장 좋겠지만, 이런 상황이 생길 수도 있습니다.

이럴 때 인스턴스변수의 앞에 this를 붙여주시면 이 변수는 인스턴스 변수라고 컴파일러에게 알려주는 것입니다.

Tv(int width, int height){
	this.width = width;
	this.height = height;
}

이 this는 참조변수로서 인스턴스 자신을 가리킵니다. 즉 인스턴스 자신의 주소값을 저장하고 있습니다.

또한 모든 인스턴스메서드에 이 this가 지역변수로 숨겨진 채로 존재하고 있습니다.

생성자를 이용한 인스턴스 복사


생성자를 적절하게 사용하면 현재 사용하고 있는 인스턴스와 동일한 상태를 가지고 있는 인스턴스를 하나 더 만들 수도 있습니다.

여기서 동일한 상태라는 말은 두 인스턴스의 모든 인스턴스변수가 동일한 값을 갖고 있다는 뜻입니다.

Tv(Tv t){
	width = t.width;
	height = t.height;
}

위와 같이 매개변수를 참조변수로 받는 생성자를 정의하고, 이곳에 복사할 원본 인스턴스를 전달 인자로 넘겨주시면 됩니다.

public class example{
    public static void main(String[] args){
        Tv t1 = new Tv();
        Tv t2 = new Tv(t1);
        System.out.println("t1.width = " + t1.width + ", t1.height = " + t1.height);
        System.out.println("t2.width = " + t2.width + ", t2.height = " + t2.height);
    }
}
class Tv{
    int width;
    int height;
    Tv(){
        this(1920, 1080);
    }
    Tv(Tv t){
        width = t.width;
        height = t.height;
    }
    Tv(int width, int height){
        this.width = width;
        this.height = height;
        
    }
    void tvSize(){
        System.out.println("width = " + width + ", height = " + height);
    }
}

그러면 이렇게 t1과 속성이 완전하게 동일한 인스턴스인 t2가 생성됩니다.

오해하시면 안 될 점은 t2가 t1을 복사해서 생성된 인스턴스이긴 하지만, 서로 독립된 메모리 공간상에 존재하기 때문에

t1의 값을 변경해도 t2의 값은 바뀌지 않으며, 그 반대도 당연히 성립하지 않습니다.

이런 생성자를 적절하게 활용하면 보다 직관적이고, 객체지향적인 코드를 작성할 수 있을것입니다.

 

생성자에 대한 설명은 이상으로 마치도록 하겠습니다.

감사합니다.

반응형

'프로그래밍 언어 > 자바' 카테고리의 다른 글

자바 17. 상속, 포함관계  (0) 2020.09.01
자바 16. 변수의 초기화  (0) 2020.08.31
자바 14. 메서드 오버로딩  (0) 2020.08.27
자바 13. 변수의 종류, 메서드  (0) 2020.08.26
자바 12. 클래스와 객체  (0) 2020.08.25