munifico.github.io

munifico's anything page

Follow me on GitHub

상속

프로토타입을 이해하면서 우리는 이미 상속의 일면을 봤습니다. 클래스의 인스턴스는 클래스의 기능을 모두 상속합니다. 상속은 한 단계로 끝나지 않습니다. 객체의 프로토타입에서 메서드를 찾지 못하면 자바스크립트는 프로토타입의 프로토타입을 검색합니다. 프로토타입 체인은 이런식으로 만들어집니다. 자바스크립트는 조건에 맞는 프로토타입을 찾을 때까지 프로토타입 체인을 계속 거슬러 올라갑니다. 조건에 맞는 프로토타입을 찾지 못하면 에러를 일으킵니다.

클래스의 계층 구조를 만들 때 프로토타입 체인을 염두에 두면 효율적인 구조를 만들 수 있습니다. 즉, 프로토타입 체인에서 가장 적절한 위치에 메서드를 정의하는 겁니다. 자동차는 운송 수단의 일종입니다. 예를 들어 자동차에는 deployAirbags란 메서드가 있을 수 있습니다. 이 메서드를 운송 수단 클래스에 정의할 수도 있겠지만, 에어백이 달린 보트는 본 적이 없겠죠? 반면 운송 수단은 대부분 승객을 태울 수 있으므로, addPassenger 메서드는 운송 수단 클래스에 적당합니다. 이런 시나리오를 자바스크립트로 만들어 봅시다.

class Vehicle {
    constructor() {
        this.passengers = [];
        console.log('운송 수단이 생성되었습니다.');
    }
    addPassenger(p) {
        this.passengers.push(p);
    }
}

class Car extends Vehicle {
    constructor() {
        super();
        console.log('차량이 생성되었습니다.');
    }
    deployAirbags() {
        console.log('뽝!');
    }
}

처음 보는 키워드가 눈에 띕니다. extends 키워드는 Car를 Vehicle의 서브클래스로 만듭니다. super() 키워드는 슈퍼클래스(Vehicle)의 생성자를 호출하는 특별한 함수입니다. 서브클래스에서는 이 함수를 반드시 호출해야 합니다. 호출하지 않으면 에러가 일어납니다.

const v = new Vehicle();    //운송 수단이 생성되었습니다.
v.addPassenger('Kang');
v.addPassenger('Kim');
console.log(v.passengers);  //[ 'Kang', 'Kim' ]
const c = new Car();        //운송 수단이 생성되었습니다.(super()로 Vehicle() 호출)
                            //차량이 생성되었습니다.
c.addPassenger('Park');
c.addPassenger('Lee');
console.log(c.passengers);  //[ 'Park', 'Lee' ]
v.deployAirbags();          //error! 슈퍼클래스에서는 서브클래스에 접근 불가
c.deployAirbags();          //뽝!

c에서는 deployAirbags를 호출할 수 있지만, v에서는 불가능합니다. 달리 말하면, 상속은 (당연히) 단방향 입니다. Car 클래스의 인스턴스는 Vehicle 클래스의 모든 메서드에 접근할 수 있지만, 반대는 불가능합니다.


이전 : 정적 메서드
다음 : 다형성
목차