[Java] 클래스 ③

[ 생성자 ]

생성자는 new 연산자와 같이 사용되어 클래스로부터 객체를 생성할 때 호출되어 객체의 초기화를 담당한다.

  • 객체 초기화는 필드를 초기화하거나, 메소드를 호출해서 객체를 사용할 준비를 하는 것을 말한다.
  • 생성자를 실행시키지 않고는 클래스로부터 객체를 만들 수 없다.

1. 기본 생성자 ( Default Constructor )

자바의 모든 클래스는 하나 이상의 생성자가 반드시 필요하다.
만약 클래스 내부에 생성자 선언을 생략했다면 컴파일러가 기본 생성자를 바이트 코드에 자동으로 추가시킨다.

기본 생성자 형태

클래스이름() { }
  • 기본 생성자는 매개변수를 가지지 않고, 아무런 명령어도 포함하지 않는다.
  • 클래스가 public class로 선언되면 기본 생성자에도 public이 붙지만,
    클래스가 public 없이 class로만 선언되면 기본 생성자에도 public이 붙지 않는다.

예제

Car() {}

기본 생성자 덕분에 클래스에 생성자를 선언하지 않아도 다음과 같이 new 연산자를 이용하여 객체를 생성할 수 있다.

Car myCar = new Car();	//기본 생성자

클래스에 명시적으로 선언한 생성자가 하나라도 있다면, 컴파일러는 기본 생성자를 생성하지 않는다!
그러므로 만약 기본 생성자가 필요하다면 기본 생성자를 명시적으로 선언해주어야 한다.


2. 생성자 선언

생성자 선언 방법

클래스이름(매개변수선언, ... ) {
    //객체의 초기화 코드
}

생성자는 리턴 타입이 없고, 클래스 이름과 동일하다.

예제

  • 생성자 선언
public class Car {

    //생성자
    Car(String color, int cc) {
    }

}
  • 생성자를 호출해서 객체 생성
public class CarExample {
    public static void main(String[] args) {
        Car myCar = new Car("red", 3000);
        //Car myCar = new Car(); <- 기본 생성자를 호출할 수 없다.
}

3. 필드 초기화

클래스로부터 객체가 생성될 때 필드는 기본 초기값으로 자동 설정된다.

만약 다른 값으로 초기화하고 싶다면

  • 필드를 선언할 때 초기값을 주거나
  • 생성자에서 초기값을 주는 방법

두 가지가 있다.

필드를 선언할 때 초기값을 주게 되면 동일한 클래스로부터 생성되는 객체들은 모두 (객체 생성 시점에는) 같은 데이터를 갖게 된다.

public class Korean {

    String nation = "Korea";
    String name;
    int age;
    
}

위의 예제의 경우, Korean 객체의 nation 값은 모두 "Korea"이다.

하지만 객체 생성 시점에 외부에서 제공되는 다양한 값들로 초기화되어야 한다면 생성자에서 초기화를 해야 한다.
위의 코드에서 nameage 필드값은 객체 생성 시점에 다양한 값을 가져야 하기 때문에 생성자의 매개값으로 값들을 받아 초기화해주어야 한다.

public class Korean {

    //필드
    String nation = "Korea";
    String name;
    int age;
    
    //생성자
    public Korean(String n, int a) {
        name = n;
        age = a;
    }
    
}

보통 매개 변수의 이름은 필드 이름과 비슷하거나 동일한 이름을 사용한다.
그렇다고 다음과 같이 사용하면 안된다!

public Korean(String name, int age) {
    name = name;
    age = age;
}

필드와 매개 변수 이름이 동일할 때, 매개 변수가 사용 우선순위가 높기 때문에 생성자 내부에서 해당 필드에 접근할 수 없다!
그래서 다음과 같이 필드명 앞에 this.를 붙여줘야 한다.

public Korean(String name, int age) {
    this.name = name;
    this.age = age;
}

4. 생성자 오버로딩( Overloading )

자바에서는 다양한 방법으로 객체를 생성할 수 있도록 생성자 오버로딩을 제공한다.
생성자 오버로딩이란 매개 변수를 달리하는 생성자르 여러 개 선언하는 것을 말한다.

예제

public class Person {

    String name;
    int age;
    
    Person() {
    }
    
    Person(String name) {
        this.name = name;
    }
    
    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
}

생성자 오버로딩 시 주의할 점은 매개 변수의 타입과 개수, 그리고 선언된 순서가 똑같을 경우 매개 변수 이름만 바꾸는 것은 생성자 오버로딩이라고 할 수 없다!

Car(String model, String color) { ... }
Car(String color, String model) { ... }	//오버로딩이 아니다!

생성자가 오버로딩되어 있을 경우,
new 연산자로 생성자를 호출할 때 제공되는 매개값의 타입과 수에 의해 호출된 생성자가 결정된다.

Car car1 = new Car();				//Car() (기본 생성자) 호출
Car car2 = new Car("그랜저");			//Car(String model) 생성자 호출
Car car3 = new Car("그랜저", "흰색");		//Car(String model, String color) 생성자 호출
Car car4 = new Car("그랜저", "흰색", 300);	//Car(String model, String color, int maxSpeed) 생성자 호출

5. 다른 생성자 호출( this() )

생성자 오버로딩이 많아질 경우, 생성자 간의 중복된 코드가 발생할 수 있다.
특히 매개 변수의 수만 달리하고 필드 초기화 내용이 비슷한 생성자일 때 많이 발생한다.

이 경우 필드 초기화 내용은 한 생성자에게만 집중적으로 작성하고
나머지 생성자는 초기화 내용을 가지고 있는 생성자를 호출하는 방법으로 개선할 수 있다.

생성자에서 다른 생성자를 호출할 때는 this() 코드를 사용한다.

  • this()는 자신의 다른 생성자를 호출하는 코드로, 반드시 생성자의 첫 줄에서만 허용된다.
  • this()의 매개값은 호출되는 생성자의 매개 변수 타입에 맞게 제공해야 한다.
  • this() 다음에는 추가적인 실행문들이 올 수 있다. 이 경우, 호출되는 생성자의 실행이 끝나면 원래 생성자로 돌아와서 다음 실행문을 진행한다.

다음과 같이 this()를 사용하여 중복 코드를 제거할 수 있다.


좋은 웹페이지 즐겨찾기