생성자 호출부터 super(), super

byeol·2023년 7월 14일

생성자 호출

먼저 위 개념을 배우기 위해서 생성자 호출 방식에 대해서 다시 한번 살펴보도록 할게요

클래스에서 extends의 개념은 is a kind의 개념입니다

독수리는 새의 한 종류인 것처럼 말입니다.

따라서 새가 없다면 독수리는 없습니다.

그렇기 때문에 독수리를 생성하기 위해서는 새가 먼저 생성되어야 합니다.

결국 모든 클래스의 최상위 클래스인 Object를 가장 먼저 생성합니다.

그러나 생각해보면 클래스를 만들 때 생성자에 Object를 호출한 적이 있나요?

아마 없을 겁니다.

그 이유는 Object는 생성자가 기본생성자만 있기 때문에

자동으로 컴파일러가 내가 만든 클래스의 인스턴스를 만들 때 Object의 기본생성자를 호출해 줍니다.

예시를 하나 만들어 보았습니다.

독수리를 생성하기 위해서 새를 호출해야 하는데 호출하지 않습니다.

자동으로 호출해주었기 때문입니다.

class Bird {
    int wing;
    int beak;
}

class Eagle extends Bird {
    int sky;

    public Eagle(int sky) {
        this.sky = sky;
    }

}

class New {
    public static void main(String[] args) {
        Eagle eagle = new Eagle(3);
        System.out.println("sky: " + eagle.sky);//3
        System.out.println("beak: " + eagle.beak);//0
        System.out.println("wing: " + eagle.wing);//0

    }
}

그렇다면 만약에 Bird에 기본생성자가 아닌 다른 생성자가 있다면

어떻게 해야할까요?

super()

super()를 통해서 가능합니다.

위는 super()가 생략된 것입니다.

class Eagle extends Bird {
    int sky;

    public Eagle(int sky) {
        //super(); 생략 가능
        this.sky = sky;
    }

}
class New {
    public static void main(String[] args) {
        Eagle eagle = new Eagle(3);
        System.out.println("sky: " + eagle.sky);//3
        System.out.println("beak: " + eagle.beak);//0
        System.out.println("wing: " + eagle.wing);//0

    }
}

따라서 위 예시를 보면 eagle.beek과 eagle.wing는 Bird에서 가져오게 되기 때문에 출력하면 0이 나옵니다.

미리 호출되어 Bird를 생성했다는 것을 증명해주는 결과입니다.

그렇다면 기본 생성자가 아닌 경우 호출하는 방식을 살펴보겠습니다.

class Bird {
    int wing;
    int beak;

    Bird(int wing, int beak){
        this.wing = wing;
        this.beak = beak;
    }
}

class Eagle extends Bird {
    int sky;

    public Eagle(int sky) {
        super(3,4);
        this.sky = sky;
    }

}

class New {
    public static void main(String[] args) {
        Eagle eagle = new Eagle(3);
        System.out.println("sky: " + eagle.sky);//3
        System.out.println("beak: " + eagle.beak);//3
        System.out.println("wing: " + eagle.wing);//4

    }
}

위와 같이 Bird에 기본 생성자 없는 경우 혹은 기본생성자와 매개변수가 있는 생성자가 있는 경우에는 반드시 super()를 통해서 자신의 출처?를 호출해야합니다.

super

super는 상속하는 과정에서 같은 이름의 메서드와 인스턴스 변수를 사용할 때 이를 구분하기 위해서 사용됩니다.

상속이라는 것은 개념을 확장하는 것이고

super를 통해서도 확장이 가능합니다.

하나의 예시를 작성해보았습니다.

class Car {
    int wheel =10;
    int door;

    Car(){
        this(1,1);
    }

    Car(int wheel, int door) {
        this.wheel = wheel;
        this.door = door;
    }

    public void openDoor() {
        System.out.println("문을 자동으로 열다");
    }
}

class Truck extends Car {
    int wheel = 20;
    public Truck(int wheel, int door) {
        super(wheel, door);
    }
    void printTruck(){
        System.out.println("truck의 wheel: "+this.wheel);
    }

    void printCar(){
        System.out.println("car의 wheel: "+super.wheel);
    }

    @Override
    public void openDoor() {
        super.openDoor();
        System.out.println("지붕을 열 수 있다.");
    }
}

class Main {
    public static void main(String[] args) {
        Truck truck = new Truck(2, 4);

        truck.setTruckWheel(20);
        truck.printTruck(); // 출력: 20
        truck.printCar(); //출력 : 40
        System.out.println(truck.wheel);
        System.out.println();

        truck.setCarWheel(30);
        truck.printCar(); // 출력: 30
        truck.printTruck(); // 출력 : 20
        System.out.println();
        System.out.println();

        truck.openDoor();
    }
}

Car의 openDoor 메서드 이름과 Truck의 openDoor 메서드 이름은 같습니다.

위 예시를 보면 이를 구분하고 Car의 개념을 확장하기 위해서

super.openDoor를 통해서 Car의 openDoor를 호출하고

여기에 Truck의 기능(지붕이 자동으로 열린다)을 더 추가하여 확장하고 있습니다.

또한 wheel의 인스턴스 변수가 중복되어 정의되어 있어 Car의 wheel과 Truck의 wheel를 구분하여 사용하기 위해서 super와 this를 사용합니다.

profile
꾸준하게 Ready, Set, Go!

0개의 댓글