- new 연산자를 통해서 인스턴스를 생성할 때 반드시 호출이 되고 제일 먼저 실행되는 일종의 메소드. 생성자는 인스턴스 변수(필드 값 등)를 초기화 시키는 역할을 함.
- 생성자 없이는 클래스로부터 객체를 만들 수 없음.
- new 연산자에 의해 생성자가 성공적으로 실행되면, 힙 영역에 객체가 생성되고 객체의 주소가 반환되고 해당 객체주소는 클래스 타입 변수에 저장되어 객체에 접근할 때 이용됨.
- 모든 클래스는 생성자가 반드시 존재하며 하나 이상을 가질 수 있음.
- 생성자는 반드시 클래스명과 동일하게 정의하여야한다.
- 생성자 앞에서는 접근제한자만 올수 있으며 반환 값이 없으므로 void나 자료형을 작성할 수 없다.
- 클래스 내부에 생성자 선언을 생략 했다면 컴파일러는 기본 생성자 (Default Constructor)를 바이트 코드에 자동 추가 시킨다.
- 클래스가 public class로 선언되면 기본생성자에도 public이 붙지만 클래스가 public 없이 선언되면 기본생성자에도 public이 붙지 않는다.
[public] class명() { }
- 클래스라는 부분은 생성자를 정의하는 클래스의 이름과 동일하게 적어줘야 함.
- 생성자 블록 내부에는 객체 초기화 코드를 작성하여 일반적으로 필드에 초기값을 저장하거나 메소드를 호출하여 객체 사용 전 필요한 준비를 진행.
- 매개 변수 선언은 생략할 수 있고, 생성자는 여러개를 선언할 수 있다.
- 매개 변수는 new 연산자로 생성자 호출 시 외부의 값을 생성자 블록 내부로 전달하는 역할을 한다.
public class명(매개변수) { ... }
- 클래스로부터 객체가 생성될 때 필드는 기본 초기값으로 자동 설정된다. 다른 값으로 초기화하고 싶다면 필드를 선언 시 초기값을 주거나 생성자에서 초기값을 주는 방법(매개변수)가 있다. 필드를 선언할 때 초기값을 주게 되면 클래스로부터 생성되는 객체들은 모두 같은 데이터를 갖게 된다.
- 생성자를 이용하여 매개변수를 이용한 초기화는 관례적으로 필드와 동일한 이름을 사용하며, 해당 클래스의 필드를 접근하기 위해 this를 이용한다.
- 필드 선언 초기화
public class Car{ String nation = "Korea"; }
- 생성자 생성 시 초기화
public class Car{ // 필드 String nation; String name; // 생성자 public Car(String nation, String name){ this.nation = nation; // this를 이용하여 class 필드 접근 this.name = name; } }
- 생성자 오버로딩 : 매개 변수를 달리하는 생성자를 여러 개 선언이 가능하도록 하는 것
- 외부에서 제공되는 다양한 데이터들을 이용해서 객체를 초기화 하기위해서는 생성자도 다양화 되어야 함.
- 객체를 생성 시 외부에서 제공되는 데이터에 따라서 객체를 생성하는데, 자바는 제공되는 데이터에 따라 다양한 방법으로 객체를 생성할 수 있돌고 생성자 오버로딩을 제공함.
- 생성자 오버로딩 시 매개 변수의 타입과 개수, 선언된 순서가 같은 경우 ( 매개 변수의 이름만 다른 경우 )는 생성자 오버로딩으로 볼 수 없음
- 생성자가 오버로딩 되어 있는 경우, new 연산자로 생성자를 호출할 때, 제공되는 매개값의 타입과 개수에 의해 호출될 생성자가 결정됨.
public class Car{ Car(){ ... } Car(String model){ ... } Car(String model, String color){ ... } Car(String model, String color, int maxSpeed){ ... } }
- 인스턴스를 생성할 때 생성자를 호출한다.
- 같은 객체를 생성하더라도 매개변수에 따라서 다른 생성자를 호출하여 여러 방식으로 생성이 가능하다.
Car car1 = new Car(); // new Car(); 부분에서 생성자를 호출하여 인스턴스 생성함
- 생성자 오버로딩이 많아질 경우 생성자간 중복코드 발생
- 매개 변수의 수만 다르게 하고 필드 초기화 내용이 비슷한 생성자에서 많이 발생하는데 이런 경우 필드초기화내용은 한 생성자에서만 집중적으로 작성하고, 나머지 생성자는 초기화 내용을 가지고 있는 생성자를 호출하는 방법으로 개선.
- 위의 문제를 해결하기 위해, 생성자에서 다른 생성자를 호출할 때는 this()를 이용하는데, this()는 다른 생성자를 호출하는 코드로 반드시 생성자의 첫 줄에서만 허용된다.
- this()의 매개값은 호출되는 생성자에 매개 변수 타입에 맞게 제공되어야 함.
- this()다음에는 추가적인 실행문들이 올 수 있음.
public class Car { //필드 String company = "Hyundai"; String model; String color; int maxSpeed; //기본 생성자 Car() { } Car(String model) { // 생성자1 this(model, "silver", 250); // 생성자3 호출함 } Car(String model, String color) { //생성자2 this(model, color, 250); // 생성자3 호출 } Car(String model, String color, int maxSpeed) { //생성자3 this.model = model; // 공통 실행 코드 this.color = color; // 공통 실행 코드 this.maxSpeed = maxSpeed; // 공통 실행 코드 } }
* 오버로딩 vs 오버라이딩?
- 오버로딩과 오버라이딩은 객체지향의 특징인 다형성을 위해 자바에서 자주 사용
- 오버로딩 (Overloading) : 같은 메서드 이름, 다른 인자 목록에서 다수의 메서드를 중복 정의
- 오버라이딩 (Overrding) : 같은 메서드 이름, 같은 인자 목록에서 상위 클래스의 메서드를 재정의
* 클래스, 객체, 인스턴스란?
- 클래스 ( Class ) : 객체를 만들어 내기 위한 설계도 혹은 틀, 연관되어 있는 변수와 메소드의 집합
- 객체 ( Object ) : 소프트웨어 세계에 구현할 대상. 클래스에 선언된 모양 그대로 생성된 실체로 클래스의 인스턴스(Instance)라고 부름. 객체는 모든 인스턴스를 대표하는 포괄적인 의미를 갖고 OOP 관점에서 클래스의 타입으로 선언되었을 때 객체라고 부름
- 인스턴스 ( Instance ) : 설계도를 바탕으로 소프트웨어 세계에 구현된 구체적인 실체. 객체를 소프트웨어에 실체화하면 그것을 인스턴스라고 부름. 실체화된 인스턴스는 메모리에 할당된다. 인스턴스는 객체에 포함되고 OOP 관점에서 객체가 메모리에 할당되어 실제 사용될 때 인스턴스라고 부름. 인스턴스는 주로 추상적인 개념(명세)와 구체적인 객체 사이의 관계에 초점을 맞출 경우 사용함.
비교
- 클래스 vs 객체 : 클래스는 설계도, 객체는 설계도로 구현한 모든 대상을 의미
- 객체 vs 인스턴스 : 클래스 타입으로 선언될 때 객체, 그 객체가 메모리에 할당되어 실제 사용될 때 인스턴스. 객체는 ‘실체’ 인스턴스는 ‘관계’에 초점
추상화 기법
- 분류 ( Classification ) : 객체 -> 클래스. 실재하는 객체들을 공통적인 속성을 공유하는 범부 또는 추상적인 개념으로 묶는 것
- 인스턴스화 ( Instantiation ) : 클래스 -> 인스턴스. 분류의 반대 개념. 범주나 개념으로부터 실재하는 객체를 만드는 과정. 예시 ( Exemplification ) 라고도 부름
- 생성자는 특별한 메서드로 상속되지 않으며 오버라이딩이 되지 않아 수정될 가능성이 없어 수정을 제한할 의미가 없음
- 생성자는 본질적으로 수정할 수 없기 때문에 final 키워드가 필요 없음
- final을 사용하면 컴파일 에러 발생
- static은 클래스의 객체가 아닌 클래스에 속하게 되는데 클래스는 이미 정적으로 존재
- 'static'이라는 키워드는 클래스 자체에 속하는 것을 의미하며 클래스에 모든 인스턴스에 공유됨
- 반면 생성자는 클래스의 인스턴스를 생성하기 위한 메서드
- 생성자는 클래스의 객체가 생성될 때 호출하므로 성립이 되지 않음
- 정적 생성자를 선언하면 하위 클래스에선 생성자에 접근하거나 호출할 수 없음
22-06-20