상속과 확장
extends 로 물려받고 super 로 부모를 호출합니다.
이미 있는 것을 물려받습니다
할인 상품은 상품이면서 할인율이 더 있는 것입니다. 상품 클래스를 그대로 다시 적는 대신 물려받아 필요한 것만 더합니다.
extends— 물려받을 클래스를 적습니다.super(...)— 부모의constructor를 부릅니다.super.메서드()— 부모의 메서드를 부릅니다.
물려받아 더하기
class Product { constructor(name, price) { this.name = name; this.price = price; } describe() { return `${this.name} ${this.price}원`; } } class SaleProduct extends Product { constructor(name, price, percent) { super(name, price); this.percent = percent; } get salePrice() { return Math.floor(this.price * (100 - this.percent) / 100); } } const item = new SaleProduct("공책", 2000, 10); console.log(item.name); console.log(item.describe()); console.log(item.salePrice);
name 과 describe 를 적지
않았는데 그대로 사용합니다. 부모에 있는 것은 자식에도 있습니다.
같은 이름으로 다르게
부모와 같은 이름의 메서드를 두면 자식 것이 쓰입니다. 부모 것도 함께
쓰려면 super 로 부릅니다.
class Product { constructor(name, price) { this.name = name; this.price = price; } describe() { return `${this.name} ${this.price}원`; } } class SaleProduct extends Product { constructor(name, price, percent) { super(name, price); this.percent = percent; } describe() { return `${super.describe()} → ${this.percent}% 할인`; } } const plain = new Product("연필", 1000); const sale = new SaleProduct("공책", 2000, 10); console.log(plain.describe()); console.log(sale.describe());
같은 이름으로 함께 다루기
부모가 같으면 한 배열에 담아 같은 이름으로 부를 수 있습니다. 각자 자기 것으로 움직입니다.
class Product { constructor(name) { this.name = name; } label() { return this.name; } } class SaleProduct extends Product { label() { return `[할인] ${this.name}`; } } class NewProduct extends Product { label() { return `[신상] ${this.name}`; } } const items = [ new Product("연필"), new SaleProduct("공책"), new NewProduct("지우개") ]; items.forEach(item => console.log(item.label()));
부르는 쪽은 어느 클래스인지 몰라도 됩니다. 새 종류를 더해도 이 코드는 그대로입니다.
어느 클래스인지 확인하기
class Product {} class SaleProduct extends Product {} const sale = new SaleProduct(); console.log(sale instanceof SaleProduct); console.log(sale instanceof Product); console.log(new Product() instanceof SaleProduct); console.log(sale.constructor.name);
자식은 부모이기도 합니다. 반대는 아닙니다.
처음에 자주 걸리는 것
자식에 constructor 를 두었으면
this 를 쓰기 전에
super() 를 먼저 불러야 합니다.
ReferenceError: Must call super constructor in derived class before accessing 'this'
세 단계를 넘어가면 어느 메서드가 어디에서 왔는지 알기 어려워집니다. 대개는 물려받는 대신 필요한 것을 넘겨받는 편이 낫습니다(2.6).
# 을 붙인 필드는 그 클래스 안에서만
보입니다. 자식도 밖입니다. 자식에게 열어 주려면 get
을 두세요(6.1).
직접 해보기
이름을 받는 Member 와, 등급을 더 받는
PremiumMember 를 만드세요. 인사말은 각각
"홍길동님" 과
"홍길동님 (골드)" 입니다.
Shape 를 물려받는 사각형과 원을 만들고, 배열에
담아 넓이를 차례로 출력하세요. 원주율은
Math.PI 입니다.
이 단원의 정리
extends로 물려받고 필요한 것만 더합니다.- 자식에
constructor를 두면super()를 먼저 부릅니다. - 같은 이름의 메서드를 두면 자식 것이 쓰입니다. 부모 것은
super.로 부릅니다. - 부모가 같으면 한 배열에 담아 같은 이름으로 부를 수 있습니다.
- 세 단계를 넘어가면 물려받는 대신 넘겨받는 편이 낫습니다.