[Java 개념노트 31] super 키워드 이해하기
안녕하세요. Java 개념노트 시리즈 서른한 번째 글입니다.
지난 글에서는 부모 클래스의 메서드를 자식 클래스에서 다시 정의하는 메서드 오버라이딩에 대해 정리했습니다. 이번 글에서는 상속 관계에서 부모 클래스의 필드, 메서드, 생성자를 가리킬 때 사용하는 super 키워드에 대해 알아보겠습니다.
상속을 사용하면 자식 클래스는 부모 클래스의 필드와 메서드를 물려받을 수 있습니다. 그런데 자식 클래스에서 부모의 멤버를 명확하게 가리키고 싶거나, 부모 생성자를 호출해야 할 때가 있습니다. 이럴 때 사용하는 것이 super입니다.
1. super란?
super는 자식 클래스에서 부모 클래스를 가리킬 때 사용하는 키워드입니다.
지난 글에서 this는 현재 객체 자기 자신을 가리킨다고 했습니다. 반면 super는 현재 객체 안에 포함된 부모 클래스 부분을 가리킨다고 이해하면 됩니다.
쉽게 말하면super는 자식 클래스 안에서 부모 클래스의 필드나 메서드에 접근할 때 사용하는 키워드입니다.
2. this와 super의 차이
this와 super는 모두 객체와 관련된 키워드입니다. 하지만 가리키는 대상이 다릅니다.
| 키워드 | 의미 | 사용 예 |
this |
현재 객체 자기 자신 | this.name |
super |
부모 클래스 부분 | super.name |
자식 클래스 안에서 this는 현재 자식 객체를 의미하고, super는 그 자식 객체 안의 부모 클래스 부분을 의미합니다.
3. super로 부모 필드 접근하기
자식 클래스와 부모 클래스에 같은 이름의 필드가 있을 때 super를 사용하면 부모 클래스의 필드를 명확하게 가리킬 수 있습니다.
public class Main {
public static void main(String[] args) {
Child child = new Child();
child.printName();
}
}
class Parent {
String name = "부모 이름";
}
class Child extends Parent {
String name = "자식 이름";
void printName() {
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
}
}
실행 결과는 다음과 같습니다.
자식 이름
자식 이름
부모 이름
name과 this.name은 자식 클래스의 필드를 의미합니다. 반면 super.name은 부모 클래스의 필드를 의미합니다.
핵심 포인트
부모와 자식 클래스에 같은 이름의 필드가 있을 때, 부모 필드를 명확히 가리키려면 super.필드명을 사용합니다.
4. super로 부모 메서드 호출하기
오버라이딩한 메서드 안에서 부모 클래스의 원래 메서드를 호출하고 싶을 때 super.메서드명()을 사용할 수 있습니다.
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.sound();
}
}
class Animal {
void sound() {
System.out.println("동물이 소리를 냅니다.");
}
}
class Dog extends Animal {
@Override
void sound() {
super.sound();
System.out.println("멍멍");
}
}
실행 결과는 다음과 같습니다.
동물이 소리를 냅니다.
멍멍
super.sound()는 부모 클래스인 Animal의 sound() 메서드를 호출합니다. 그다음 자식 클래스의 추가 코드인 멍멍이 실행됩니다.
5. 부모 기능을 유지하면서 확장하기
오버라이딩을 할 때 부모의 기능을 완전히 바꾸는 경우도 있지만, 부모 기능을 먼저 실행한 뒤 자식 기능을 추가하는 경우도 많습니다.
public class Main {
public static void main(String[] args) {
VipMember vipMember = new VipMember("건", 10);
vipMember.printInfo();
}
}
class Member {
String name;
Member(String name) {
this.name = name;
}
void printInfo() {
System.out.println("회원 이름: " + name);
}
}
class VipMember extends Member {
int discountRate;
VipMember(String name, int discountRate) {
super(name);
this.discountRate = discountRate;
}
@Override
void printInfo() {
super.printInfo();
System.out.println("할인율: " + discountRate + "%");
}
}
실행 결과는 다음과 같습니다.
회원 이름: 건
할인율: 10%
자식 클래스의 printInfo()에서 super.printInfo()를 먼저 호출했습니다. 그래서 부모의 회원 이름 출력 기능을 유지하면서, VIP 회원의 할인율 출력 기능을 추가할 수 있습니다.
6. super()란?
super()는 부모 클래스의 생성자를 호출할 때 사용하는 문법입니다.
객체를 생성할 때 자식 객체만 만들어지는 것이 아닙니다. 자식 객체 안에는 부모 클래스 부분도 함께 만들어집니다. 그래서 자식 객체를 만들 때 부모 클래스 부분을 먼저 초기화해야 합니다. 이때 부모 생성자가 호출됩니다.
class Parent {
Parent() {
System.out.println("Parent 생성자");
}
}
class Child extends Parent {
Child() {
super();
System.out.println("Child 생성자");
}
}
super()는 부모 클래스의 기본 생성자를 호출합니다.
7. 부모 생성자가 먼저 호출된다
자식 객체를 생성하면 부모 생성자가 먼저 실행되고, 그다음 자식 생성자가 실행됩니다.
public class Main {
public static void main(String[] args) {
Child child = new Child();
}
}
class Parent {
Parent() {
System.out.println("Parent 생성자 실행");
}
}
class Child extends Parent {
Child() {
System.out.println("Child 생성자 실행");
}
}
실행 결과는 다음과 같습니다.
Parent 생성자 실행
Child 생성자 실행
Child 생성자 안에 super()가 보이지 않지만, 자바가 자동으로 부모의 기본 생성자를 호출합니다.
기억하기
자식 객체를 만들 때는 부모 클래스 부분이 먼저 초기화되어야 하므로 부모 생성자가 먼저 실행됩니다.
8. super()는 생략될 수 있다
자식 생성자에서 super()를 직접 작성하지 않아도, 부모 클래스에 기본 생성자가 있다면 자바가 자동으로 super()를 넣어줍니다.
class Parent {
Parent() {
System.out.println("Parent 생성자");
}
}
class Child extends Parent {
Child() {
System.out.println("Child 생성자");
}
}
위 코드는 내부적으로 다음과 비슷하게 동작합니다.
class Child extends Parent {
Child() {
super();
System.out.println("Child 생성자");
}
}
즉, 부모의 기본 생성자를 호출하는 super()는 자동으로 추가될 수 있습니다.
9. 부모에게 기본 생성자가 없으면?
부모 클래스에 매개변수가 있는 생성자만 있고 기본 생성자가 없다면, 자식 생성자에서 반드시 부모 생성자를 직접 호출해야 합니다.
class Parent {
Parent(String name) {
System.out.println("Parent name: " + name);
}
}
class Child extends Parent {
Child() {
System.out.println("Child 생성자");
}
}
위 코드는 오류가 발생합니다. 부모 클래스에 Parent() 기본 생성자가 없는데, 자식 생성자에서 자동으로 super()를 호출하려고 하기 때문입니다.
이럴 때는 자식 생성자에서 부모 생성자를 명시적으로 호출해야 합니다.
class Parent {
Parent(String name) {
System.out.println("Parent name: " + name);
}
}
class Child extends Parent {
Child() {
super("부모값");
System.out.println("Child 생성자");
}
}
super("부모값")을 통해 부모의 매개변수 생성자를 직접 호출했습니다.
10. super()는 생성자의 첫 줄에 있어야 한다
super()는 생성자 안에서 반드시 첫 번째 줄에 작성해야 합니다.
올바른 예
class Child extends Parent {
Child() {
super();
System.out.println("Child 생성자");
}
}
잘못된 예
class Child extends Parent {
Child() {
System.out.println("Child 생성자");
super(); // 오류 발생
}
}
부모 클래스 부분이 먼저 초기화되어야 하므로 super()는 생성자 첫 줄에 와야 합니다.
주의super()는 부모 생성자를 호출하는 문법이며, 생성자의 첫 번째 줄에 작성해야 합니다.
11. this()와 super()는 함께 첫 줄에 올 수 없다
this()는 같은 클래스의 다른 생성자를 호출하고, super()는 부모 생성자를 호출합니다. 둘 다 생성자의 첫 줄에 와야 하므로 같은 생성자에서 둘을 동시에 첫 줄에 작성할 수 없습니다.
class Child extends Parent {
Child() {
this("자식");
super(); // 오류 발생
}
Child(String name) {
super();
}
}
한 생성자 안에서는 this() 또는 super() 중 하나만 첫 줄에 올 수 있습니다.
다만 this()로 다른 생성자를 호출하면, 호출된 생성자 안에서 결국 super()가 실행될 수 있습니다.
12. this와 super 비교
this와 super를 다시 비교해보겠습니다.
| 구분 | this | super |
| 의미 | 현재 객체 자기 자신 | 부모 클래스 부분 |
| 필드 접근 | this.name |
super.name |
| 메서드 호출 | this.print() |
super.print() |
| 생성자 호출 | this()는 같은 클래스의 다른 생성자 호출 |
super()는 부모 생성자 호출 |
| 주 사용 상황 | 현재 객체 필드와 매개변수 구분 | 부모 멤버나 부모 생성자 호출 |
13. super와 private 멤버
super를 사용해도 부모의 private 필드나 메서드에는 직접 접근할 수 없습니다.
class Parent {
private String name = "부모";
}
class Child extends Parent {
void printName() {
System.out.println(super.name); // 오류 발생
}
}
name은 부모 클래스의 private 필드이므로 자식 클래스에서 접근할 수 없습니다. super를 사용해도 접근 제한은 그대로 적용됩니다.
필요하다면 부모 클래스에 public 또는 protected 메서드를 만들어 접근해야 합니다.
class Parent {
private String name = "부모";
protected String getName() {
return name;
}
}
class Child extends Parent {
void printName() {
System.out.println(super.getName());
}
}
14. super 전체 예제
이번에는 super를 필드, 메서드, 생성자에서 함께 사용하는 예제를 보겠습니다.
public class Main {
public static void main(String[] args) {
DiscountProduct product = new DiscountProduct("키보드", 50000, 5000);
product.printInfo();
}
}
class Product {
String name;
int price;
Product(String name, int price) {
this.name = name;
this.price = price;
}
void printInfo() {
System.out.println("상품명: " + name);
System.out.println("가격: " + price);
}
}
class DiscountProduct extends Product {
int price;
int discountAmount;
DiscountProduct(String name, int price, int discountAmount) {
super(name, price);
this.price = price - discountAmount;
this.discountAmount = discountAmount;
}
@Override
void printInfo() {
super.printInfo();
System.out.println("할인 금액: " + discountAmount);
System.out.println("할인 후 가격: " + this.price);
System.out.println("부모의 원래 가격: " + super.price);
}
}
실행 결과는 다음과 같습니다.
상품명: 키보드
가격: 50000
할인 금액: 5000
할인 후 가격: 45000
부모의 원래 가격: 50000
super(name, price)는 부모 생성자를 호출합니다. super.printInfo()는 부모의 메서드를 호출합니다. super.price는 부모 클래스의 price 필드를 의미합니다.
15. super 사용 시 자주 하는 실수
super를 처음 배울 때는 아래와 같은 실수를 자주 합니다.
| 실수 | 문제점 | 해결 방법 |
super()를 첫 줄이 아닌 곳에 작성 |
컴파일 오류 발생 | super()는 생성자 첫 줄에 작성 |
부모 기본 생성자가 없는데 super() 생략 |
부모 생성자를 찾지 못함 | super(값)으로 부모 생성자 직접 호출 |
this()와 super()를 같은 생성자에서 함께 호출 |
둘 다 첫 줄이어야 해서 불가능 | 둘 중 하나만 사용 |
super로 private 필드 접근 |
접근 제한 때문에 오류 발생 | getter나 protected 메서드 사용 |
this와 super를 혼동 |
현재 객체와 부모 부분을 헷갈림 | this는 현재 객체, super는 부모 부분 |
16. 직접 연습해보기
아래 코드를 직접 작성하고 실행해보세요.
public class Main {
public static void main(String[] args) {
VipMember vip = new VipMember("건", 1000, 10);
vip.printInfo();
}
}
class Member {
String name;
int point;
Member(String name, int point) {
this.name = name;
this.point = point;
}
void printInfo() {
System.out.println("회원 이름: " + name);
System.out.println("포인트: " + point);
}
}
class VipMember extends Member {
int discountRate;
VipMember(String name, int point, int discountRate) {
super(name, point);
this.discountRate = discountRate;
}
@Override
void printInfo() {
super.printInfo();
System.out.println("VIP 할인율: " + discountRate + "%");
}
}
실행 결과는 다음과 같습니다.
회원 이름: 건
포인트: 1000
VIP 할인율: 10%
17. 이번 글 정리
이번 글에서는 상속 관계에서 부모 클래스를 가리키는 super 키워드에 대해 정리했습니다. 핵심 내용은 다음과 같습니다.
super는 자식 클래스에서 부모 클래스 부분을 가리키는 키워드이다.super.필드명으로 부모 클래스의 필드에 접근할 수 있다.super.메서드명()으로 부모 클래스의 메서드를 호출할 수 있다.super()는 부모 클래스의 생성자를 호출한다.- 자식 객체를 생성하면 부모 생성자가 먼저 실행되고 자식 생성자가 실행된다.
- 부모 기본 생성자가 있으면
super()는 생략될 수 있다. - 부모 기본 생성자가 없으면 자식 생성자에서
super(값)을 직접 호출해야 한다. super()는 생성자의 첫 번째 줄에 작성해야 한다.this()와super()는 같은 생성자에서 동시에 첫 줄에 올 수 없다.super를 사용해도 부모의 private 멤버에는 직접 접근할 수 없다.
한 줄 요약super는 부모 클래스의 필드와 메서드에 접근하거나 부모 생성자를 호출할 때 사용하는 상속 전용 키워드입니다.
다음 글 예고
다음 글에서는 [Java 개념노트 32] 다형성이란 무엇인가?라는 주제로 부모 타입으로 자식 객체를 다루는 객체지향 핵심 개념을 정리해보겠습니다.
GWDEVELBlog Java 개념노트 시리즈

'Computer Science > Java' 카테고리의 다른 글
| [Java] 개념노트 33 참조변수의 형변환과 instanceof 이해하기 (0) | 2026.06.13 |
|---|---|
| [Java] 개념노트 32 다형성이란 무엇인가? (0) | 2026.06.13 |
| [Java] 개념노트 30 메서드 오버라이딩 이해하기 (0) | 2026.06.12 |
| [Java ] 개념노트29 상속이란 무엇인가? (0) | 2026.06.11 |
| [Java] 개념노트 28 패키지와 import 이해하기 (0) | 2026.06.10 |