본문 바로가기
JAVA & Spring

[Java] super란? super()란? 아주 쉽게 정리(+코드)

by 알기 쉬운 코딩 사전 2025. 1. 7.
반응형

super란?

Java에서 super 키워드는 상속 관계에서 자식 클래스가 부모 클래스에 접근 하기 위해 사용 되는 키워드(예약어)입니다.
super 키워드 사용 방식은 다음 2가지가 있습니다.

  • 부모 참조: super.value
  • 생성자: super(...)

 

super - 부모 참조

부모와 자식의 필드명이 같거나 메서드가 오바라이딩 되어 있으면, 자식에서 부모의 필드나 메서드를 호출할 수 없습니다.
 
이때 super 키워드를 사용하면 부모를 참조할 수 있습니다.
 
다음 코드를 살펴봅시다.
 
부모의 필드명과 자식의 필드명이 둘다 value로 똑같습니다.
메서드도 hello()로 자식에서 오버라이딩 되어 있습니다.
이때 자식 클래스에서 부모 클래스의 valuehello()를 호출하고 싶다면 super 키워드를 사용하면 됩니다.
 
Parent.java

public class Parent {
    public String value = "parent";

    public void hello() {
        System.out.println("Parent.hello");
    }
}

 
Child.java

public class Child extends Parent{
    public String value = "child";

    @Override
    public void hello() {
        System.out.println("Child.hello");
    }

    public void call() {
        System.out.println("this value = " + this.value); // this 생략 가능
        System.out.println("super value = " + super.value);

        // hello() // Child.hello 출력
        this.hello(); // this 생략 가능
        super.hello();
    }
}
참고: call() 메서드에서 hello()를 호출하게 되면 자동으로 this가 생략되므로 Child.hello가 출력됩니다.

 
SuperMain.java

public class SuperMain {
    public static void main(String[] args) {
        Child child = new Child();
        child.call();
    }
}

 
실행 결과

this value = child
super value = parent
Child.hello
Parent.hello

실행 결과를 보면 super를 사용한 경우 부모 클래스의 기능을 사용한 것을 확인할 수 있습니다.
 

super 메모리 그림

 

super - 생성자

상속 관계의 인스턴스를 생성하면 결국 메모리 내부에는 자식과 부모 클래스가 각각 다 만들어집니다. (super 메모리 그림 참고)
Child를 만들면 부모인 Parent 까지 함께 만들어지는 것입니다. 따라서 각각의 생성자도 모두 호출되어야 합니다.
 
상속 관계를 사용하면 자식 클래스의 생성자에서 부모클래스의 생성자를 반드시 호출해야 합니다.
상속 관계에서 부모의 생성자를 호출할 때는 super(...)를 사용하면 됩니다.
 
예제를 통해 상속 관계에서 생성자를 어떻게 사용하는지 알아봅시다.
 
ClassA.java

public class ClassA {
    public ClassA() {
        System.out.println("ClassA 생성자");
    }
}
ClassA는 최상위 부모 클래스입니다.

 
ClassB.java

public class ClassB extends ClassA{
    public ClassB(int a) {
        super(); // 기본 생성자 생략 가능
        System.out.println("ClassB 생성자 a=" + a);
    }

    public ClassB(int a, int b) {
        super(); // 기본 생성자 생략 가능
        System.out.println("ClassB 생성자 a=" + a + "b=" + b);
    }
}
ClassBClassA를 상속 받았습니다.
상속을 받으면 생성자의 첫줄에 super(...)를 사용해서 부모 클래스의 생성자를 호출해야 합니다.

부모 클래스의 생성자가 기본 생성자(파라미터가 없는 생성자)인 경우에는 super()를 생략할 수 있습니다.
상속 관계에서 첫줄에 super(...)를 생략하면 자바는 부모의 기본 생성자를 호출하는 super()를 자동으로 만들어줍니다.

 
ClassC.java

public class ClassC extends ClassB {
    public ClassC() {
        super(10, 20);
        System.out.println("ClassC 생성자");
    }
}
ClassCClassB를 상속 받았습니다. ClassB는 2개의 생성자가 있습니다.
생성자는 하나만 호출할 수 있습니다. 두 생성자 중에 하나를 선택하면 됩니다.

참고로 ClassC의 부모인 ClassB에는 기본 생성자가 없습니다.
따라서 부모의 기본 생성자를 호출하는 super()를 사용하거나 생략할 수 없습니다.

 
Super2Main.java

public class Super2Main {
    public static void main(String[] args) {
        ClassC classC = new ClassC();
    }
}

 
실행 결과

ClassA 생성자
ClassB 생성자 a=10 b=20
ClassC 생성자

 
실행해보면 ClassA -> ClassB -> ClassC 순서로 실행됩니다.
생성자의 실행 순서가 결과적으로 최상위 부모부터 실행되어서 하나씩 아래로 내려오는 것입니다.
 
따라서 초기화는 최상위 부모부터 이루어집니다. 
왜냐하면 자식 생성자의 첫 줄에서 부모의 생성자를 호출해야 하기 때문입니다.

반응형

댓글