Menu
Coddy logo textTech

깊은 상속의 한계

Coddy JavaScript 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 56개 중 48번째.

상속은 유용하지만, 매우 깊은 상속 계층 구조(부모 → 자식 → 손자 → 증손자)를 만드는 것은 문제를 일으킬 수 있습니다. 계층 구조가 깊어질수록 코드를 이해하고 유지 관리하며 수정하는 것이 더 어려워집니다.

깊은 상속 체인에서 어떤 일이 일어나는지 살펴봅시다:

// Base class
class Vehicle {
  constructor(type) {
    this.type = type;
    this.isRunning = false;
  }
  
  start() {
    this.isRunning = true;
    console.log(`${this.type} started`);
  }
}

// First level of inheritance
class Car extends Vehicle {
  constructor(make, model) {
    super("Car");
    this.make = make;
    this.model = model;
    this.wheels = 4;
  }
  
  honk() {
    console.log("Beep beep!");
  }
}

// Second level of inheritance
class SportsCar extends Car {
  constructor(make, model, topSpeed) {
    super(make, model);
    this.topSpeed = topSpeed;
  }
  
  race() {
    this.start();
    console.log(`Racing at ${this.topSpeed} mph!`);
  }
}

이 예제에서 SportsCar는 상속 구조에서 2단계 깊이에 있습니다. 이는 몇 가지 문제로 이어질 수 있습니다:

  1. Vehicle에 대한 변경 사항이 예기치 않게 SportsCar를 망가뜨릴 수 있습니다
  1. 상속 체인이 길어질수록 메서드와 속성이 어디에서 오는지 추적하기가 더 어려워집니다
  1. 충분히 유연하지 않을 수 있는 "is-a" 관계를 강요받게 됩니다
challenge icon

챌린지

로봇이 작동할 수 있도록 Robot.js 파일을 완성하세요. 현재 로봇은 조립되었지만 아무것도 할 수 없는 상태입니다.

Robot.js에서 해야 할 일:

  1. Robot 생성자 내부에서 speaker와 mover 컴포넌트를 생성하세요.
  2. 메서드에서 컴포넌트를 사용하세요:
    1. greet()에서: this.speaker.speak("Hello!");를 호출하세요.
    2. walkForward()에서: this.mover.move("forward");를 호출하세요.

이렇게 하는 이유: 이것은 합성(composition)입니다. 로봇은 더 작은 컴포넌트들을 결합하여 만들어집니다. 로봇은 이러한 능력을 상속받는 대신, 말하기 위한 speaker를 가지고 있고(has-a), 움직이기 위한 mover를 가지고 있습니다(has-a).

치트 시트

깊은 상속 계층 구조(부모 → 자식 → 손자)는 유지보수 문제와 유연성 부족을 초래할 수 있습니다. 체인이 깊어질수록 코드를 이해하고 수정하는 것이 더 어려워집니다.

깊은 상속 체인의 예시:

class Vehicle {
  constructor(type) {
    this.type = type;
    this.isRunning = false;
  }
  
  start() {
    this.isRunning = true;
    console.log(`${this.type} started`);
  }
}

class Car extends Vehicle {
  constructor(make, model) {
    super("Car");
    this.make = make;
    this.model = model;
  }
}

class SportsCar extends Car {
  constructor(make, model, topSpeed) {
    super(make, model);
    this.topSpeed = topSpeed;
  }
}

깊은 상속의 문제점:

  • 기본 클래스(base classes)의 변경이 예기치 않게 자식 클래스를 망가뜨릴 수 있음
  • 메서드와 속성이 어디에서 기원했는지 추적하기 어려움
  • 유연성이 부족한 엄격한 "is-a" 관계를 강제함

대안으로서의 구성(Composition): 상속 대신, 객체가 컴포넌트와 have-a 관계를 갖는 구성을 사용하여, 작은 부분들을 결합해 기능을 구축하십시오.

직접 해보기

import { Robot } from './Robot.js';

const myRobot = new Robot('Robo');

myRobot.greet();     // 출력 결과: Saying: "Hello!"
myRobot.walkForward(); // 출력 결과: Moving forward
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨