pwoogi
자신의 왜곡된 경험을 진실이라고 생각하지 말자

프로그래밍/JAVA

생성자 this( )

pwoogi 2022. 7. 21. 21:31

 

 

생성자..

🤦‍♂️🤷‍♂️
진짜 얘 때문에 너무 고생했다.

 

 

오늘은 생성자에 대해서 욕, 아니 이야기 해보겠다.

 

 

1. 생성자

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

 

객체를 만들때 기본적인 개념은 아래의 구조의 순서대로 흘러간다.

a. 객체생성

b. 인스턴스(iv) 초기화

c. 객체가 가지고 있는 기능(메서드) 사용

 

여기서 생성자는 인스턴스 생성시 수행할 작업(iv 초기화)에 사용된다.

 

그렇다면 어떤 조건들이 있을까?

 

  • 이름이 클래스 이름과 같아야 한다.

1. 아래의 Java 클래스 이름과 타입변수명을 적어둔 것을 확인할 수 있다.

class Java{
    int a = 5;
    int b = 4;
	
    //매개변수 없는 생성자(기본 생성자)
    Java(){
    }
    //매개변수 있는 생성자
    Java(int a, int b){
    //인스턴스 생성 시 수행될 코드,
    //주로 인스턴스 변수의 초기화 코드를 적는다.
    }
}

2. 입력받을 매개변수 명과 클래스 영역안에 선언된 변수명은 같지 않아도 되지만 타입은 같아야한다.

3. 생성자가 하나도 없을 때만 컴파일러가 기본 생성자를 자동으로 추가해준다.

class Java {
	int value;
}

class Java_one{
	int value;
    
    //Java_one(){} 기본생성자를 생성해주지 않았기 때문에
	Java_one(int x){
    	value = x;
    }
}

class Java_test{
	public static void main(String[] args){
        Java_one jo = new Java_one(); // compile error 발생!
        Java jv = new Java(); 
    }
}

4. 가장 헷갈릴 수 있는 부분인데 생성자는 new 연산자를 통해 객체를 만들어주고 생성자를 호출해서 매개변수에 입력한 값이 인스턴스에 대입되어 초기화가 이루어지는 과정이다. 아래의 내 못난 그림을 보고 이해해주면 좋겠다.

다시 정리해보자면, new 연산자를 통해 객체를 형성하고 그 주소를 저장한다. 그와 동시에 생성자를 호출하면 "hello", "hi"의 매개변수가 생성자 값을 대입해야하는 변수에 저장이 된다. 그래서 우리는 원래 변수 hello, hi에 무슨 값이 대입되어있던 매개변수로 값을 저장한 인스턴스값이 초기화된 값이다. 그래서 인스턴스값이 초기화된 변수를 사용해서 메서드내에 선언도 하게 되는 것이다.

 

 2. this ( )

생성자에서 다른 생성자 호출할 때 사용

 

생성자끼리 코드의 중복을 제거하려고 서로 호출하는 경우가 많다. 필자의 경우 이 this( ) 를 이해하려고 정말 2일동안 잠을 못잤다. 

public class Transportation {
    //대중교통 인스턴스
    protected int tsNum;
    protected int fuel;
    protected int speed;
    protected String gearBox;
    protected int maxPassenger;
    protected int passenger;
    protected int price;

    //기본 생성자
    public Transportation(){
        this.fuel = 100;
        this.speed = 0;
        this.gearBox = "운행중";
        this.tsNum = 100;
        this.maxPassenger = 50;
    }
	//매개변수 생성자
    public Transportation(int tsNum) {
        this();
        this.tsNum = tsNum;
    }

위의 경우 인스턴스 변수가 정말 많고 초기화를 시켜주어야하는 경우도 두가지가 있다. 두번째 필드를 보면 첫번째 필드에서 모두 기본값으로 설정되어있던 변수들의 일부에 값을 주고 초기화하였다. 매개변수 생성자를 보면 다른 생성자를 호출하는 this ( )를 선언하고 현재 매개변수로 들어오는 값을 원래 tsNum 값인 100을 매개변수 값으로 저장시켜서 다시 초기화한다.

만약 생성자를 생성하는데 this( )가 없다면 수많은 필드에 존재하는 생성자에 인스턴스를 복붙해줘야하는 현상이 발생할 것이다. 그렇기에 객체 생성 후 필요시 인스턴스 변수들을 적절하게 초기화해줄 때 사용한다.

 

최종 정리


public class Person
{
    private String name;
    private String country;
    private int age;

    public Person() {
        this("Empty");
    }

    public Person(String name) {
        this(name, 0);
    }

    public Person(String name, int age) {
        this(name, age, "Korea");
    }

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

    @Override
    public String toString() {
        return "name: " + name + " / age : " + age + " / country : " + country;
    }

    public static void main(String[] args) {
        Person personObj = new Person();
        
        System.out.println(personObj.toString());
    }
}

 

실행결과

 

생성자가 호출되는 과정

출처: [평범한 직장인의 공부 정리:티스토리]

 

3. Super( )

 

sub 클래스 객체를 생성할 때 생성자에서 super( )를 호출하거나 super. 키워드를 활용하여 super 클래스의 기본 생성자를 호출한다. 만약 super클래스가 상위 클래스에서 상속을 받는 경우 부모 클래스 생성자는 상위 클래스의 기본 생성자를 호출한다.

 

이 개념이 왜 중요하냐면 생성자가 없는 경우 그 상위 클래스를 타고 올라가는데 결국 최고 super 클래스인 Object 클래스의 생성자를 호출하게 된다.Object 클래서는 가장 최상위 클래서이며 모든 클래스는 이에 상속된다.

 

Objuect 클래스의 생성자가 호출되는 이유는 JVM이 자동으로 super 키워드를 생성자의 가장 첫번째 라인에 넣어주기 때문에 우리는 아래와 같이 따로 쓰지 않고 편하게 생성만 했던 것이다. 

class Memo{
	public static void main(String[] args){
    	Gongbu gb = new Gongbu(); // Gongbu() JVM에 의해 자동으로 호출되는 Object 클래스의 생성자
    }
}

 

 

좀 더 디테일한 예시를 살펴보자



 childPersonObj1의 객체를 생성하는 과정


supert 생성자의 sub class의 생성자를 호출하는 과정(1)

출처 : 평범한 직장인의 공부정리

 

 


childPersonObj2 객체를 생성하는 과정

 

정해진 규칙을 알아보자

1. 상위 클래스 생성자는 하위 클래스에서 상속될 수 없다

2. this 키워드 또는 super 키워드는 생성자의 첫 번째 줄에 작성

3. 생성자에서 this , super 키워드 두개 모두를 다 사용할 수는 없다

4. 생성자 호출이나 실행과정은 반대로 동작하기 때문에 만약 생성자를 a,b,c 순서로 호출하면 3,2,1 순서로 실행된다

5. 생성자에 super() 를 추가하지 않은 경우 JVM은 super 키워드를 생성자에 암시적으로 추가한다

6. 생성자 이름을 직접 호출 할 수 없습니다.

 

 

 

 

이번 프로젝트를 구현하면서 정말 많은 걸 깨달았다. 아직 구현하기 위한 개념들이 너무 많이 부족한 상태..

 

 

 

이번주는 일요일까지 빡세게 달린다, 모든 코린이들 화이팅😭

https://github.com/pwoogi/bus_project.git