JAVA

자바 상속 — 기존 클래스를 물려받아 확장하기(INHERITANCE·EXTENDS)

PANCO_IT
#자바#JAVA#상속#extends#오버라이딩

부모 클래스 Animal의 것을 자식 클래스 Dog이 물려받는 상속 개념 그림

자식 클래스는 부모의 공통 기능을 물려받고, 자기만의 기능을 더합니다.

강아지 클래스, 고양이 클래스를 따로 만든다고 해봅시다. 둘 다 이름이 있고 먹는 기능이 있죠. 이 공통 부분을 매번 처음부터 다시 쓸까요? 그럴 필요 없습니다. 공통은 한 번만 만들어 두고 물려받는 것이 오늘의 주제, 상속입니다.

상속이 뭔가요?

상속은 한 클래스가 다른 클래스의 필드와 메서드를 물려받는 것입니다. 물려주는 쪽을 부모(상위) 클래스, 물려받는 쪽을 자식(하위) 클래스라고 합니다.

쉽게 — 부모의 특징을 물려받는 것과 같습니다. 아이는 부모에게 받은 것(눈·머리색)에 자기만의 개성을 더하죠. 자동차로 치면 '기본 모델'을 공통으로 두고, 거기에 옵션을 더해 여러 모델을 만드는 것과 같습니다. 공통은 물려받고, 다른 점만 추가하는 것입니다.

extends로 물려받기

상속은 extends 키워드로 표시합니다. 공통 기능을 부모 클래스에 모으고, 자식은 그걸 물려받습니다.

class Animal {
    String name;
    void eat() {
        System.out.println(name + "가 먹습니다.");
    }
}

class Dog extends Animal {   // Animal을 물려받음
    void bark() {            // Dog만의 기능 추가
        System.out.println(name + ": 멍멍!");
    }
}

Dogeat()을 직접 쓴 적이 없지만, Animal에게 물려받았으니 그대로 쓸 수 있습니다. 여기에 자기만의 bark()를 더한 것입니다.

상속의 세 가지 키워드: extends, super, 오버라이딩

그림 1. 물려받고(extends), 부모를 부르고(super), 필요하면 다시 정의(오버라이딩)합니다.

물려받은 것과 새로 더한 것

객체를 만들어 보면, 물려받은 기능과 새 기능을 모두 쓸 수 있습니다.

Dog d = new Dog();
d.name = "바둑이";
d.eat();    // 물려받은 메서드 → 바둑이가 먹습니다.
d.bark();   // 새로 추가한 메서드 → 바둑이: 멍멍!

Dog 안에는 eat()을 적지 않았는데도 동작합니다. 부모에게 물려받았기 때문입니다. 같은 방식으로 Cat extends Animal을 만들면, 고양이도 eat()을 공짜로 얻고 자기만의 기능만 추가하면 됩니다. 공통 코드를 한 번만 쓰는 것이 상속의 가장 큰 이점입니다.

super — 부모 것을 부르기

자식에서 부모의 생성자나 메서드를 직접 부를 때는 super를 씁니다. super()는 부모 생성자를, super.메서드()는 부모 메서드를 가리킵니다.

class Dog extends Animal {
    void introduce() {
        super.eat();          // 부모의 eat() 실행
        System.out.println("저는 개입니다.");
    }
}

오버라이딩 — 부모 메서드를 다시 정의

물려받은 메서드가 자식에게 안 맞으면, 같은 이름으로 다시 정의할 수 있습니다. 이를 오버라이딩이라 하고, 위에 @Override를 붙여 표시합니다.

class Dog extends Animal {
    @Override
    void eat() {                         // 부모의 eat()을 새로 정의
        System.out.println(name + "가 사료를 먹습니다.");
    }
}

이제 Dogeat()은 부모 것 대신 이 내용으로 동작합니다. 공통은 물려받되, 다르게 할 부분만 골라 바꾸는 것입니다.

단골 함정 — 아무 때나 상속하지 않기

상속은 '~은 ~이다(is-a)' 관계일 때만 씁니다. "개는 동물이다"는 자연스럽지만, "개는 목줄이다"는 말이 안 되죠. 그냥 코드를 재사용하고 싶다고 관계가 어색한데 상속하면, 나중에 구조가 꼬입니다.

class Dog extends Animal { }   // OK: 개는 동물이다
class Dog extends Leash { }    // 이상함: 개는 목줄이 아니다

또 하나. 부모의 private 필드는 상속돼도 자식이 직접 접근하지는 못합니다. 이럴 땐 부모가 만든 getter/setter 같은 공개 메서드로 접근해야 합니다.

직접 실행해 보기

아래 코드를 돌려 보고, Cat extends Animal 클래스를 하나 더 만들어 eat()을 물려 써 보세요.

상속 — extends로 물려받기
class Animal {
  String name;
  void eat() {
      System.out.println(name + "가 먹습니다.");
  }
}

class Dog extends Animal {   // Animal을 물려받음
  void bark() {
      System.out.println(name + ": 멍멍!");
  }
}

public class Main {
  public static void main(String[] args) {
      Dog d = new Dog();
      d.name = "바둑이";
      d.eat();    // 물려받은 메서드
      d.bark();   // 새로 추가한 메서드
  }
}

📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.

한 장 정리

용어
상속부모 클래스의 필드·메서드를 물려받는 것
extends상속을 표시하는 키워드 class 자식 extends 부모
super부모의 생성자·메서드를 부를 때 super.eat()
오버라이딩물려받은 메서드를 자식이 다시 정의 @Override
is-a상속은 "~은 ~이다" 관계일 때만

이것만 기억하면 됩니다. 상속은 공통 기능을 부모에 모아 두고 extends로 물려받아, 자식은 다른 점만 더하는 것입니다. 부모 것을 부를 땐 super, 다르게 바꿀 땐 오버라이딩을 씁니다. 단, "~은 ~이다" 관계가 성립할 때만 상속하세요.

미니 퀴즈

개념을 제대로 잡았는지 직접 풀어 봅니다. 정답은 눌러야 나옵니다.

미니 퀴즈

OX 2문제 + 4지선다 3문제


포켓코딩(JAVA2) 7편 · 예제 출처: 강사 개인 GitHub 저장소. 다음 편: 다형성 — 하나의 타입으로 여러 자식을 다루기.

PANCO_IT

IT 지식을 정리하는 개발자

관련 글