class Drink {
constructor(ml, container) {
this.ml = ml;
this.container = container;
}
}
class Alcohol extends Drink {
constructor(ml, container, volume) {
super(ml, container)
this.volume = volume;
}
}
const alcohol = new Alcohol(700, 'bottle', 40)
console.log(alcohol) // { ml: 700, container: 'bottle', volume: 40 }
상속에 의한 클래스 확장은 기존 클래스를 상속받아 새로운 클래스를 확장하여 정의하는 것이다.
Alcohol과 Soda는 Drink에 속하므로 Drink 속성을 가지지만 각각 고유의 속성도 있다. 그래서 Alcohol과 Soda는 상속을 통해 Drink 클래스의 속성을 그대로 사용하면서 고유 속성만 추가하여 확장 가능하다.
extends
키워드는 클래스 뿐 아니라 생성자 함수를 상속받아 클래스를 확장할 수 있다.
// 생성자 함수
function Base(a) {
this.a = a;
}
// 생성자 함수를 상속받는 서브클래스
class Derived extends Base {}
const derived = new Derived(1);
console.log(derived); // Derived {a: 1}
extends
키워드 다음에는 클래스 뿐만 아니라 [[Construct]]
내부 메서드를 갖는 함수 객체로 평가될 수 있는 모든 표현식을 사용할 수 있다.
function Base1() {}
class Base2 {}
let condition = true;
class Derived extends (condition ? Base1 : Base2) {}
super
키워드는 함수처럼 호출할 수도 있고 this와 같이 식별자처럼 참조할 수 있는 특수 키워드이다.
super
를 호출하면 수퍼클래스의 constructor를 호출한다
class Base {
constructor(a, b) {
this.a = a;
this.b = b;
}
}
class Derived extends Base {
// 암묵적으로 constructor가 정의됨
// constructor(...arg) { super(...arg); }
}
const derived = new Derived(1, 2);
console.log(derived); // Derived {a: 1, b: 2}
하지만 처음 설명한 Drink 클래스의 서브클래스처럼 내부에 추가된 프로퍼티가 있다면 constructor를 생략할 수 없다. super
키워드의 특징은 다음과 같다.
super
를 호출하기 전엔 this 참조 불가super
는 반드시 서브클래스의 constructor에서만 호출super를 참조하면 수퍼클래스의 메서드를 호출할 수 있다
class Base {
constructor(name) {
this.name = name;
}
sayHi() {
return `Hi, ${this.name}`;
}
}
class Derived extends Base {
sayHi() {
return `${super.sayHi()}. How are you?`;
}
}
const derived = new Derived('ming');
console.log(derived); // Hi, ming. How are you?
정적 메서드도 이와 같은 방식으로 호출할 수 있다.