상속

상속 에서 JavaScript

1개의 연습 문제

상속 소개

상속은 클래스 사이에 부모-자식 관계를 만드는 방법이에요. 자식 클래스(때때로 _서브클래스_라고도 해요)는 부모 클래스(때때로 _슈퍼클래스_라고도 해요)가 정의한 동작과 데이터에 접근할 수 있어요.

class Pet {
  constructor(name) {
    this.name = name;
  }

  introduce() {
    console.log(`This is my pet, ${this.name}.`);
  }
}

class Dog extends Pet {}

const dog = new Dog('Otis');
dog.introduce();
// => This is my pet, Otis.

자식 클래스 선언에서 extends 키워드는 프로토타입 체인을 통해 부모 클래스와의 관계를 맺어요.

자식의 생성자로 만든 객체는 프로토타입 체인에 부모 클래스의 프로토타입을 가지게 되어, 부모가 정의한 모든 메서드나 데이터에 접근할 수 있어요.

const dog = new Dog('Otis');

Dog.prototype.isPrototypeOf(dog); // => true
Pet.prototype.isPrototypeOf(dog); // => true
Pet.prototype.isPrototypeOf(Dog.prototype); // => true

Pet.prototype.hasOwnProperty('introduce'); // => true
Dog.prototype.hasOwnProperty('introduce'); // => false
dog.hasOwnProperty('introduce'); // => false

생성자

자식 클래스가 생성자 함수를 정의하지 않으면, 부모의 생성자 함수가 사용돼요. 하지만 자식 클래스가 자신만의 생성자 함수를 정의하면, 부모 생성자를 명시적으로 호출해야 해요. 자식 생성자의 스코프 안에서 부모 생성자를 호출하려면 super 키워드를 사용해요.

class Pet {
  constructor(name) {
    this.name = name;
  }
}

class Dog extends Pet {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }
}

const dog = new Dog('Otis', 'Pug');

부모 생성자는 새 객체를 초기화하고 이를 this에 할당하는 역할을 하기 때문에, 자식 생성자가 this를 사용하기 전에 호출해야 해요.

class Dog extends Pet {
  constructor(name, breed) {
    // using 'this' before calling the parent constructor with 'super'
    this.breed = breed;
    super(name);
  }
}

const dog = new Dog('Otis', 'Pug');
// => ReferenceError: Must call super constructor in derived class before accessing 'this'...

자식 클래스에 메서드 정의하기

자식 클래스는 부모에게 상속받은 동작 외에도 자신만의 동작을 정의할 수 있어요.

이것이 상속을 사용하는 핵심 이유 중 하나예요. 부모 클래스가 제공하는 공통된 메서드와 데이터로 연결되면서, 각자 고유한 데이터와 메서드를 가진 특화된 자식 클래스를 만들기 위해서예요.

class Dog extends Pet {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }

  describe() {
    console.log(`${this.name} is a ${this.breed}.`);
  }
}

const dog = new Dog('Otis', 'Pug');
dog.introduce();
dog.describe();
// => 'This is my pet, Otis.'
// => 'Otis is a Pug.'

부모 클래스에서 상속받은 메서드 재정의하기

자식 클래스는 부모가 정의한 메서드의 동작을 재정의해서, 자식 클래스가 정의한 동작으로 바꾸거나 확장할 수도 있어요.

class Cat extends Pet {
  // replacing parent class behavior
  introduce() {
    console.log(`This is my cat, ${this.name}.`);
  }
}

class Dog extends Pet {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }

  describe() {
    console.log(`${this.name} is a ${this.breed}.`);
  }

  // extending parent class behavior
  introduce() {
    super.introduce();
    this.describe();
  }
}

const cat = new Cat('Milo');
cat.introduce();
// => 'This is my cat, Milo.'

const dog = new Dog('Otis', 'Pug');
dog.introduce();
// => This is my pet, Otis.
// => Otis is a Pug.

자식 클래스에서 같은 이름의 메서드 본문에서 부모 클래스에 정의된 메서드를 호출하려면, 부모를 참조하기 위해 super 키워드를 사용해야 해요.

GitHub에서 편집 링크가 새 창이나 탭에서 열려요

상속 배우기