1. 생성자 선언과 호출
📄 '생성자 constructor' 는 객체가 생성될 때 객체를 초기화하는 특수한 메서드. ( = 인스턴스 초기화 메서드 )
클래스 변수 = new 클래스();
- new 연산자는 객체를 생성한 후 생성자를 호출해서 객체를 초기화하는 역할을 한다
- 생성자가 성공적으로 실행이 끝나면 new 연산자는 객체의 주소를 리턴
- 리턴된 주소는 클래스 변수에 대입되어 객체의 필드나 메소드에 접근 할 때 이용
1) 기본 생성자
👾 모든 클래스는 생성자가 존재하며 하나 이상을 가질 수 있다.
👾 클래스에 생성자 선언이 없으면 컴파일러는 다음과 같은 기본 생성자를 바이트코드 파일에 자동으로 추가시킨다.
➡️ 그렇기 때문에 new 연산자 뒤에 기본 생성자를 호출할 수있다.
➡️ 개발자가 명시적으로 선언한 생성자가 있다면 컴파일러는 기본 생성자를 추가하지 않는다.
[public] 클래스() { }
- 클래스가 public class로 선언되면 기본 생성자도 public이 붙지만, 클래스가 public 없이 class로만 선언되면 기본 생성자에도 public이 붙지 않는다.
2) 생성자 선언
클래스(매개변수,...) {
// 객체의 초기화 코드
}
👾 생성자는 메소드와 비슷한 모양을 가지고 있으나, 리턴 타입이 없고 클래스 이름과 동일
👾 매개변수는 new 연산자로 생성자를 호출할 때 매개값을 생성자 블록 내부로 전달하는 역할
public class Car {
// 생성자 선언
Car(String model, String color, int maxSpeed) { }
}
public class CarExample {
public static void main(String[] args) {
Car myCar = new Car("그랜저", "검정", 250);
// Car myCar = new Car(); // 기본 생성자 호출 못함
}
}
필드 초기화
📍 객체마다 동일한 값을 갖고 있다면 필드 선언 시 초기값을 대입
📍 객체마다 다른 값을 가져야 한다면 생성자에서 필드를 초기화
class Pizza {
int size;
String type;
public Pizza() { // 매개변수가 없는 생성자
size = 12;
type = "슈퍼슈프림";
}
public Pizza(int s, String t) { // 매개변수가 있는 생성자
size = s;
type = t;
}
}
public class PizzaTest {
public static void main(String[] args) {
Pizza pizza1 = new Pizza();
System.out.println("(" + pizza1.type + ", " + pizza1.size + ")"); // (슈퍼슈프림, 12)
Pizza pizza2 = new Pizza(24,"포테이토");
System.out.println("(" + pizza2.type + ", " + pizza2.size + ")"); // (포테이토, 24)
}
}
this 키워드
📍 매개변수명이 필드명과 동일한 경우 필드임을 구분하기 위해 ths 키워드를 필드명 앞에 붙여줌
📍 this는 현재 객체를 말하며, this.name은 현재 객체의 데이터(필드)로서의 name을 뜻함
public class Korean {
// 필드 선언
String nation = "대한민국";
String name;
String ssn;
// 생성자 선언
public Korean(String name, String ssn) {
this.name = name;
this.ssn = ssn;
}
}
3) 생성자 오버로딩 Overloading
👾 매개값으로 객체의 필드를 다양하게 초기화하려면 생성자 오버로딩이 필요
👾 생성자 오버로딩이란 매개변수를 달리하는 생성자를 여러 개 선언하는 것을 말함
public class Car {
Car() { ... }
Car(String model) { ... }
Car(String model, String color) { ... }
Car(String model, String color, int maxSpeed) { ... }
}
- 매개변수의 타입, 개수, 순서가 다르게 여러 개의 생성자 선언
- new 연산자로 생성자를 호출할 때 제공되는 매개값의 타입과 수에 따라 실행될 생성자가 결정됨.
// 오버로딩 아닌 경우
Car(String model, String color) { ... }
Car(String color, String model) { ... }
public class Car {
//필드 선언
String company = "현대";
String model;
String color;
int maxSpeed;
//생성자 선언
Car() {}
Car(String model) {
this.model = model;
}
Car(String model, String color) {
this.model = model;
this.color = color;
}
Car(String model, String color, int maxSpeed) {
this.model = model;
this.color = color;
this.maxSpeed = maxSpeed;
}
}
public class CarExample {
public static void main(String[] args) {
Car car1 = new Car();
System.out.println("car1.company : " + car1.company);
System.out.println();
Car car2 = new Car("자가용");
System.out.println("car2.company : " + car2.company);
System.out.println("car2.model : " + car2.model);
System.out.println();
Car car3 = new Car("자가용", "빨강");
System.out.println("car3.company : " + car3.company);
System.out.println("car3.model : " + car3.model);
System.out.println("car3.color : " + car3.color);
System.out.println();
Car car4 = new Car("택시", "검정", 200);
System.out.println("car4.company : " + car4.company);
System.out.println("car4.model : " + car4.model);
System.out.println("car4.color : " + car4.color);
System.out.println("car4.maxSpeed : " + car4.maxSpeed);
}
}
다른 생성자 호출
📍 생성자 오버로딩이 많아질 경우 생성자 간의 중복된 코드가 발생할 수 있다.
📍 이 경우 공통 코드를 한 생성자에만 집중적으로 작성하고, 나머지 생성자는 this(...)를 사용하여 공통 코드를 가지고 있는 생성자를 호출하는 방법으로 개선
Car(String model) {
this.model = model;
this.color = "은색";
this.maxSpeed = 250;
}
Car(String model, String color) {
this.model = model;
this.color = color;
this.maxSpeed = 250;
}
Car(String model, String color, int maxSpeed) {
this.model = model;
this.color = color;
this.maxSpeed = maxSpeed;
}
↓
Car(String model) {
this(model, "은색", 250);
}
Car(String model, String color) {
this(model, color, 250);
}
Car(String model, String color, int maxSpeed) {
// 공통 초기화 코드
this.model = model;
this.color = color;
this.maxSpeed = maxSpeed;
}
- this( 매개값, ... )는 생성자의 첫 줄에 작성되며 다른 생성자를 호출하는 역할을 한다.
- 호출하고 싶은 생성자의 매개변수에 맞게 매개값을 제공하면 됨.
- this() 다음에는 추가적인 실행문을 작성할 수 있는데, 호출되는 생성자의 실행이 끝나면 원래 생성자로 돌아와서 다음 실행문을 실행한다.
응용 문제
- 학생을 나타내는 클래스 Student를 만든다.
- 학생은 이름(name)과 학번(rollNo), 나이(age)를 가진다.
- 메서드는 생성자만 가진다.
- 생성자를 실행하면 아래의 결과값이 출력된다.
학생의 이름 : Kim
학생의 학번 : 0001
학생의 나이 : 20
Student 객체가 생성되었습니다.
class Student{
String name;
String rollNo;
int age;
public Student(String name, String rollNo, int age){
this.name = name;
this.age = age;
this.rollNo = rollNo;
System.out.println("학생의 이름 : " + name); // 학생의 이름 : Kim
System.out.println("학생의 학번 : " + rollNo); // 학생의 학번 : 0001
System.out.println("학생의 나이 : " + age); // 학생의 나이 : 20
System.out.println("Student 객체가 생성되었습니다.");
}
}
public class Test {
public static void main(String[] args) {
Student student = new Student("Kim", "0001", 20);
}
}
* 내용 참고 - 책 '이것이 자바다'
'Programming Language > JAVA' 카테고리의 다른 글
[Java] final 필드와 상수 · 접근 제한자 (0) | 2024.08.11 |
---|---|
[Java] 인스턴스 멤버와 정적 멤버 (0) | 2024.08.10 |
[Java] 객체 지향 프로그래밍 (OOP) · 객체와 클래스 · 필드 (0) | 2024.08.10 |
[Java] JVM 메모리 구조 · 오버로딩 (0) | 2024.08.09 |
[Java] 메소드 (method) 선언과 구현 · 호출 · 종류 (0) | 2024.08.09 |