7.2 상속 (Inheritance)
자바에서 상속(Inheritance) 이란, 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 객체지향 프로그래밍의 핵심 개념입니다.
현실 세계에서 자식이 부모의 유산을 상속받듯, 자바에서는 하위(자식) 클래스가 상위(부모) 클래스의 필드와 메서드를 그대로 물려받아 사용할 수 있습니다. 이를 통해 공통적인 코드를 줄여 유지보수성을 크게 높일 수 있습니다.
1. 상속의 특징과 extends 키워드
자바에서 상속을 구현하려면, 새로 만들 자식 클래스 이름 뒤에 extends 키워드를 쓰고 상속받고자 하는 부모 클래스 이름을 명시합니다.
class 부모클래스 {
// 부모의 필드와 메서드
}
class 자식클래스 extends 부모클래스 {
// 자신만의 고유한 필드와 메서드 (부모의 것도 사용 가능)
}
- 부모 클래스(Parent Class): 상속을 해주는 클래스. 슈퍼 클래스(Super Class) 또는 상위 클래스라고도 부릅니다.
- 자식 클래스(Child Class): 상속을 받는 클래스. 서브 클래스(Sub Class) 또는 하위 클래스라고도 부릅니다.
예제: 상속의 기본
가장 이해하기 쉬운 예제로 게임의 '캐릭터'를 만들어 보겠습니다.
// 부모 클래스: 모든 캐릭터의 공통 속성
class Character {
String name;
int hp;
void walk() {
System.out.println(name + "이(가) 걷습니다. (뚜벅뚜벅)");
}
}
// 자식 클래스: Character를 상속받은 전사
class Warrior extends Character {
int rage; // 전사만의 독자적인 필드
void attack() {
System.out.println("전사 " + name + "이(가) 검으로 공격합니다! 챙!");
}
}
// 자식 클래스: Character를 상속받은 마법사
class Magician extends Character {
int mp; // 마법사만의 독자적인 필드
void castSpell() {
System.out.println("마법사 " + name + "이(가) 파이어볼을 시전합니다! 펑!");
}
}
public class InheritanceExample {
public static void main(String[] args) {
Warrior w = new Warrior();
w.name = "타락파워전사"; // 부모 필드 물려받음
w.hp = 1000; // 부모 필드 물려받음
w.rage = 100; // 본인 필드
w.walk(); // 부모 메서드 호출
w.attack(); // 본인 메서드 호출
Magician m = new Magician();
m.name = "아시안느";
m.hp = 500;
m.mp = 1500;
m.walk();
m.castSpell();
}
}
위 예제를 보면 Warrior 클래스 안에는 name이나 walk()가 없지만, extends Character를 통해 마치 자신의 것처럼 사용할 수 있습니다! 코드가 아주 간결해지고, 나중에 "모든 캐릭터는 뛰는(run()) 기능도 있어야 해!"라고 할 때 Character 클래스 한 곳만 수정하면 되므로 매우 효율적입니다.
2. 자바 상속의 중요한 규칙들
- 단일 상속(Single Inheritance)만 지원:
- C++ 등과 달리, 자바는 클래스 간의 다중 상속을 금지 합니다. 즉, 하나의 자식 클래스는 오직 하나의 부모 클래스만 가질 수 있습니다.
class Child extends Father, Mother { }이렇게 쓸 수 없습니다. (관계를 명확히 하고 모호성을 피하기 위함입니다.)
- 모든 클래스의 최고 조상,
Object클래스:- 자바에서 여러분이 만드는 모든 클래스는 (아무것도 상속받지 않더라도) 자동적으로 자바의 최상위 클래스인
java.lang.Object를 상속받게 됩니다. - 여러분이 자주 썼던
toString(),equals()같은 메서드들이 바로 이Object클래스가 물려준 메서드들입니다.
- 자바에서 여러분이 만드는 모든 클래스는 (아무것도 상속받지 않더라도) 자동적으로 자바의 최상위 클래스인
- 생성자는 상속되지 않는다:
- 부모 클래스의 멤버 변수와 멤버 메서드는 상속되지만, 생성자와 초기화 블럭은 상속되지 않습니다. 하지만 자식 클래스의 생성자가 호출될 때 묵시적으로 부모 클래스의 기본 생성자가 먼저 호출되어 초기화를 돕습니다.
3. 부모 클래스를 가리키는 super와 super()
이전 장에서 내 자신을 가리키는 키워드 this를 배웠습니다. 이와 유사하게 자식 클래스 내부에서 부모 클래스 를 지칭할 때 사용하는 것이 super입니다.
super: 자식 클래스에서 물려받은 부모의 변수나 메서드를 가리키는 참조 변수 입니다.super(): 부모 클래스의 생성자 를 호출하는 메서드입니다.
super() 생성자 호출 예제
자식 객체를 생성하면, 부모 객체의 성질도 포함되어야 하므로 메모리 공간에 부모 부분도 같이 만들어져야 합니다. 자바는 이를 위해 자식의 생성자 첫 줄에서 무조건 부모의 생성자 super()를 호출하도록 강제합니다. (여러분이 안 쓰면 컴파일러가 첫 줄에 자동으로 super();를 끼워 넣습니다.)
class Parent {
int x;
Parent() {
System.out.println("Parent 기본 생성자 호출!");
this.x = 10;
}
}
class Child extends Parent {
int y;
Child() {
// 컴파일러가 여기에 super(); 를 자동으로 삽입합니다.
System.out.println("Child 기본 생성자 호출!");
this.y = 20;
}
}
public class SuperExample {
public static void main(String[] args) {
Child c = new Child();
}
}
[실행 결과]
Parent 기본 생성자 호출!
Child 기본 생성자 호출!
자바 상속(Inheritance)은 코드 복제(Ctrl+C, Ctrl+V)의 불편함을 덜고 잘 짜인 공통 로직을 한 곳에 모아 효율적으로 관리하는 필수 기법입니다. 다음 챕터 7.3에서는 상속받은 부모의 메서드를 자식이 입맛에 맞게 개조(Overriding)하는 방법과 상속의 꽃인 다형성(Polymorphism)을 배웁니다.