생성자(Constructor)

  • 인스턴스가 생성될 때 호출되는 ‘인스턴스 초기화 메서드’

  • 사용

    • 인스턴스 변수의 초기화 작업에 주로 사용

    • 인스턴스 초기화 : 인스턴스 변수들을 초기화 하는 것

    • 인스턴스 생성시에 실행되어야 할 작업을 위해서도 사용

  • 메서드와의 차이

    • 메서드처럼 클래스 내부에 선언

    • 구조도 비슷함

    • (다른점) 리턴값이 없다는 점. void를 적지 않고, 아무것도 적지 않음

  • 생성자의 조건

    • 생성자의 이름은 클래스의 이름과 같아야 함

    • 생성자는 리턴 값이 없음
      (생성자도 메서드이기 때문에 리턴값이 없다는 의미의 void를 붙여야하지만, 모든 생성자가 리턴값이 없으므로 void를 생략할 수 있게 함)

  • 연산자 new가 인스턴스를 생성하는 것이지, 생성자가 인스턴스를 생성하는 것이 아님

  • 오버로딩 가능

  • 인스턴스 생성 순서 (예 - 클래스 Weather에 대하여)

    • 연산자 new에 의해서 메모리(heap)에 Weather클래스(예)의 인스턴스가 생성

    • 생성자 Weather()가 호출되어서 수행

    • 연산자 new의 결과로, 생성된 Weather인스턴스 주소가 반환되어 참조변수에 저장



기본 생성자(default constructor)

  • 모든 클래스에는 반드시 하나 이상의 생성자가 정의되어 있어야 함

  • 클래스에 생성자가 하나도 없을 경우, 컴파일러가 기본생성자를 제공함

    • 컴파일시 .java(소스파일)의 클래스에 생성자가 하나도 정의되지 않았다면, 컴파일러는 자동으로 기본 생성자를 생성

    • 클래스이름() { }

  • 매개변수도 내용도 없이 간단함

  • (주의) 만일 생성자 ‘클래스이름(ab) { }’ 를 생성한다면, 해당 클래스가 ‘클래스이름()’으로 호출될 수 있다면, ‘클래스이름() { }’도 수동으로 생성해줘야 함

    • 컴파일러는 생성자가 한 개도 없을 때만 기본 생성자를 생성해줌



매개변수가 있는 생성자

  • 생성자도 메서드처럼 매개변수를 선언하여 호출 시 값을 넘겨받아서 인스턴스의 초기화 작업에 사용할 수 있음

    • 인스턴스를 생성한 후 인스턴스변수의 값을 변경하는 것보다 매개변수를 갖는 생성자를 사용하는 것이 간결하고 직관적

    • 다양한 생성자를 제공함으로써 인스턴스 생성 후에 별도로 초기화를 하지 않아도 되도록 하는 것이 바람직



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

  • this(), this(매개변수)

    • 생성자, 같은 클래스의 다른 생성자를 호출할 때 사용

    • 생성자 간에도 서로 호출이 가능

    • 같은 클래스 내의 생성자들은 일반적으로 서로 관계가 깊은 경우가 많아서, 서로 호출하여 유기적으로 연결해주면 더 좋고 유지보수가 쉬운 코드를 얻을 수 있음

    • 조건1. 생성자의 이름으로 클래스이름 대신 this를 사용

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

Weather() {
    today = "sunny";   
    Weather("1");     // 에러 1. this("1");로 호출해야 함 (생성자 이름 대신 this)
}                     // 에러 2. 생성자의 첫 줄에서만 호출이 가능함
  • this

    • 참조변수로 인스턴스 자신을 가리킴, 인스턴스의 주소가 저장되어 있음

    • static 멤버는 사용 불가

    • 참조변수를 통해 인스턴스의 멤버에 접근할 수 있는 것처럼, this로 인스턴스변수에 접근 가능

    • 생성자를 포함한 모든 인스턴스메서드에는 자신이 관련된 인스턴스를 가리키는 참조변수 ‘this’가 지역변수로 숨겨진 채로 존재

    • static 메서드의 경우 인스턴스와 관련 없는 기능이므로 배제



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

// 생성자로 복사하기 위한 생성자 정의
Weather(Weather w) {
    today = w.today;
    yesterday = w.yesterday;
    tomorrow = w.tomorrow;
}

// 이렇게도 가능
Weather(Weather w) {
    // Weather(String today, String yesterday, String tomorrow);
    this(w.today, w.yesterday, w.tomorrow);
}

// 위와 같이 정의되어 있다면 다음과 같이 복사하면 됨
Weather korea = new Weather();
Weather China = new Weahter(korea); // korea의 복사본 china 생성(new를 이용했기 때문에 복사)
  • 인스턴스를 생성할 때는 다음 2가지 사항을 결정할 것

    • 클래스 - 어떤 클래스의 인스턴스를 생성할 것인가?

    • 생성자 - 선택한 클래스의 어떤 생성자로 인스턴스를 생성할 것인가?