[JS ES6] 객체지향5. class를 복사하는 extends / super

gminnimk·2025년 3월 20일

JS ES6

목록 보기
17/31

class, prototype, constructor에 익숙한 분들을 위한 심화 내용입니다. ES6의 extendssuper를 사용하여 기존 클래스를 상속하고 확장하는 방법을 알아봅니다.


1️⃣ extends를 이용한 클래스 상속

1-1. extends란?

  • extends는 기존 클래스를 그대로 복사하여 새로운 클래스를 만들 때 사용합니다.
  • 이를 통해 중복 코드를 줄이고, 부모 클래스의 속성과 메소드를 그대로 상속받을 수 있습니다.

1-2. 기본 예제: 할아버지 → 아버지

// 부모(할아버지) 클래스 정의
class 할아버지 {
  constructor(name) {
    this.= 'Kim';
    this.이름 = name;
  }
}

// 할아버지 클래스를 상속받아 아버지 클래스 생성
class 아버지 extends 할아버지 {}

// new 연산자를 통해 인스턴스 생성
const a = new 아버지('만수');
console.log(a); // { 성: 'Kim', 이름: '만수' }
  • 설명:
    • extends를 사용하여 할아버지의 모든 속성과 메소드를 아버지 클래스에 복사합니다.
    • 별도의 추가 내용이 없으므로 할아버지와 동일한 속성을 가집니다.

2️⃣ 서브클래스에서 새로운 속성 추가하기 & super()

2-1. 추가 속성을 위한 constructor 작성

  • 만약 아버지 클래스에서 새로운 속성(예: 나이)을 추가하고 싶다면, constructor를 새로 작성해야 합니다.
  • 중요: 서브클래스의 constructor에서는 반드시 super()를 먼저 호출해야 합니다.
    • super()는 부모 클래스의 constructor를 실행하는 함수로, 부모가 가진 속성(예: 성, 이름)을 초기화합니다.

2-2. 올바른 사용 예제

class 할아버지 {
  constructor(name) {
    this.= 'Kim';
    this.이름 = name;
  }
}

class 아버지 extends 할아버지 {
  constructor(name) {
    super(name);      // 부모의 constructor를 호출하여 '성'과 '이름'을 상속받음
    this.나이 = 50;   // 아버지만의 추가 속성
  }
}

const a = new 아버지('만수');
console.log(a); // { 성: 'Kim', 이름: '만수', 나이: 50 }
  • 설명:
    • super(name)을 통해 할아버지 클래스의 constructor가 실행되어, this.성this.이름이 설정됩니다.
    • 그 후, this.나이에 추가 값을 할당합니다.

3️⃣ 부모 클래스의 메소드 상속 및 super 사용하기

3-1. 메소드 상속

  • 부모 클래스에 정의된 메소드는 서브클래스에서도 그대로 사용할 수 있습니다.
  • 예를 들어, 할아버지 클래스에 정의된 sayHi() 메소드는 아버지 클래스 인스턴스에서도 호출할 수 있습니다.
class 할아버지 {
  constructor(name) {
    this.= 'Kim';
    this.이름 = name;
  }
  sayHi() {
    console.log('안녕 나는 할아버지');
  }
}

class 아버지 extends 할아버지 {
  constructor(name) {
    super(name);
    this.나이 = 50;
  }
}

const a = new 아버지('만수');
a.sayHi();  // 출력: 안녕 나는 할아버지

3-2. 서브클래스에서 부모 메소드 호출하기 (super 메소드)

  • 서브클래스에서 부모의 메소드를 그대로 활용하면서 추가 기능을 구현할 때, super를 메소드 내에서 사용합니다.
  • super는 여기서 부모 클래스의 prototype 메소드를 가리킵니다.
class 할아버지 {
  constructor(name) {
    this.= 'Kim';
    this.이름 = name;
  }
  sayHi() {
    console.log('안녕 나는 할아버지');
  }
}

class 아버지 extends 할아버지 {
  constructor(name) {
    super(name);
    this.나이 = 50;
  }
  sayHi2() {
    console.log('안녕 나는 아버지');
    super.sayHi(); // 부모의 sayHi() 호출
  }
}

const a = new 아버지('만수');
a.sayHi2();
// 출력:
// 안녕 나는 아버지
// 안녕 나는 할아버지
  • 설명:
    • sayHi2() 메소드에서 먼저 아버지의 인사 메시지를 출력한 후, super.sayHi()로 할아버지의 sayHi()를 호출합니다.

4️⃣ 추가: ES6 class의 기본 문법 정리

4-1. ES6 class와 constructor

  • class 키워드로 객체 생성 로직을 단순화할 수 있습니다.
  • constructor()는 객체 생성 시 호출되어 초기 속성을 설정합니다.
class 부모 {
  constructor() {
    this.name = 'Kim';
  }
}
const 자식 = new 부모();

4-2. 인스턴스 메소드 추가하는 두 가지 방법

  1. constructor 내부에서 메소드 직접 추가하기

    class 부모 {
      constructor() {
        this.name = 'Kim';
        this.sayHi = function() {
          console.log('hello');
        }
      }
    }
    
  2. 클래스 내부에서 메소드 정의하기 (prototype에 추가됨)

    class 부모 {
      constructor() {
        this.name = 'Kim';
      }
      sayHi() {
        console.log('hello');
      }
    }
    
  • 설명:
    • 두 번째 방법은 메소드가 클래스의 프로토타입에 등록되므로 메모리 효율성이 좋습니다.

4-3. Object.getPrototypeOf() 사용하기

  • Object.getPrototypeOf(객체)를 통해 해당 객체가 상속받은 부모의 prototype을 확인할 수 있습니다.
  • 이는 객체가 어느 클래스에서 상속받았는지를 파악할 때 유용합니다.

4-4. 파라미터를 가진 constructor 예제

class 부모 {
  constructor(이름, 나이) {
    this.name = 이름;
    this.age = 나이;
  }
}

const 자식 = new 부모('Park', 30);
console.log(자식); // { name: 'Park', age: 30 }

4-5. prototype에 여러 메소드 추가하기

class 부모 {
  constructor(이름, 나이) {
    this.name = 이름;
    this.age = 나이;
  }
  sayHi() {
    console.log('안녕');
  }
  sayHello() {
    console.log('안녕하세요');
  }
}

const 자식 = new 부모('Park', 30);
자식.sayHi();     // 출력: 안녕
자식.sayHello();  // 출력: 안녕하세요

📌 정리

  • extends:
    • 기존 클래스를 복사하여 새로운 클래스를 만드는 문법입니다.
    • 이를 통해 코드의 중복을 줄이고, 객체지향 프로그래밍의 상속 개념을 구현할 수 있습니다.
  • super:
    • constructor 내부: 부모 클래스의 constructor를 호출하여 상속받은 속성을 초기화합니다.
    • 메소드 내부: 부모 클래스의 prototype 메소드를 호출할 때 사용합니다.
    • 두 가지 용도로 사용되므로 사용 시 위치에 따라 의미가 달라집니다.
  • ES6 class 문법의 장점:
    • 기존의 function과 prototype 기반 코드보다 가독성이 좋고, 상속 및 객체 생성이 간결해집니다.
    • 추가적인 기능(예: 파라미터 있는 constructor, 다수의 prototype 메소드 정의)도 쉽게 구현할 수 있습니다.

0개의 댓글