다중 상속은 한 클래스가 두개 이상의 상위 클래스로부터 상속을 받는 것을 뜻한다.
하지만 TypeScript는 다중 상속을 지원하지 않는다.
class A {
show(){}
}
class B {
eat(){}
}
class AB extends A, B {}
// error TS1174: Classes can only extend a single class.
이렇게 2개의 클래스, 즉 A와 B 클래스를 AB클래스에 상속을 할 수 없고, A 또는 B클래스 중 하나만 상속할 수 있다.
class A {
show() {
console.log("show of A");
}
}
class B {
eat() {
console.log("eat of B");
}
}
class AB {}
interface AB extends A, B {}
function applyMixins(targetClass: any, baseClasses: any[]): void {
baseClasses.forEach((baseClass) => {
Object.getOwnPropertyNames(baseClass.prototype).forEach((name) => {
const descriptor = Object.getOwnPropertyDescriptor(
baseClass.prototype,
name
);
descriptor &&
Object.defineProperty(targetClass.prototype, name, descriptor);
});
});
}
applyMixins(AB, [A, B]);
let ab = new AB();
ab.show(); // show of A
ab.eat(); // eat of B
코드에서 보면 AB의 instance가 담겨져 있는 ab에서 A의 show함수를, B의 eat함수를 사용하는 것을 볼 수 있다. 즉, AB가 A와B둘 다 상속을 한 것이다.
위의 코드를 보면 applyMixins함수에서 두번째가 인자들이 첫번째 인자로 받은 클래스에 상속이 된다는 흐름을 알 수 있다. 또한 AB interface에 extends A, B를 해주어 다중 상속을 할 것을 예상하게 해준다.
mixin은 다중 상속이 된다면 당연히 단일 상속도 지원을 해준다.
그렇다면 '단일 상속할 때는 class에서 extends를 해주면 더 편한거 아닌가?' 라는 생각을 할 수 있다. mixin은 상속을 유연하게 가져갈 수 있다. extends를 사용하면 중간에 다른 상속을 받고 싶어도 받을 수 없어 유연성이 떨어진다. 하지만 mixin을 사용하면 유연하게 상속을 취하고 삭제할 수도 있다.