다른 클래스를 상속받을 경우, 부모 클래스의 생성자를 호출해서 부모 클래스까지 초기화를 진행할 수 있다
클래스와 인터페이스의 차이
클래스는 객체를 생성할 수 있는 템플릿이고, 런타임에 실제로 존재하는 js 객체로 변환된다
인터페이스는 ts 문법이고, 객체의 구조를 정의하는 것이고, 런타임에는 아무런 영향도 미치지 않는다. 타입 체크를 위해서 사용된다
// ICar 라는 인터페이스 타입을 선언interface ICar {
model: string;
year: number;
start(): void;
}
// ICar 를 구현하여 구체적으로 Car 클래스를 만듦classCarimplementsICar{
constructor(public model: string, public year: number) {}
start() {
console.log(`${this.model} (${this.year}) started.`);
}
}
의존성 주입이란
객체 간의 결합도를 낮추고 객체를 생성하고 관리하는 책임을 나눠 외부에 맡기는 디자인 패턴이다
코드의 유연성과 재사용성을 높이고, 테스트하기 쉬운 구조를 만드는 데에 도움을 준다
classEngine{
start() {
console.log('Engine started');
}
}
classCar{
private engine: Engine;
// 생성자를 통해 의존성을 주입받음constructor(engine: Engine) {
this.engine = engine;
}
start() {
this.engine.start();
}
}
// 외부에서 의존성을 생성하고 주입함const engine = new Engine();
const car = new Car(engine);
car.start(); // Engine started
Car 클래스 내부에서 Engine 객체를 생성하는 것이 아닌 engine 객체를 만들고 car 를 만들 때 주입 시킴
이렇게 하면 car 는 engine 의 변화에 덜 영향 받음
상속이란
클래스가 다른 클래스를 확장하여 부모의 속성과 메서드를 물려받는 관계임
코드 재사용성을 높일 수 있음
classVehicle{
constructor(public model: string, public year: number) {}
start() {
console.log(`${this.model} (${this.year}) started.`);
}
}
classCarextendsVehicle{
constructor(model: string, year: number, public color: string) {
super(model, year);
}
start() {
super.start();
console.log(`The car is ${this.color}.`);
}
}
const car = new Car('Tesla Model 3', 2021, 'red');
car.start();
// 출력:// Tesla Model 3 (2021) started.// The car is red.
Car 클래스가 Vehicle 클래스를 상속받아서 부모의 속성과 메서드를 물려받았음 그대로 사용이 가능함
의존성 주입 vs. 상속
의존성 관리:
의존성 주입: 객체가 다른 객체에 의존성을 직접 생성하지 않고 외부에서 주입받음. 이는 객체 간의 결합도를 낮추고, 더 유연하게 관리할 수 있게 함.
상속: 클래스가 다른 클래스를 확장하여 속성과 메서드를 물려받음. 이는 코드 재사용성을 높이고, 클래스 계층 구조를 형성함.
관계의 표현:
의존성 주입: “has-a” 관계를 나타냄. 예: Car 클래스는 Engine 객체를 가짐.
상속: “is-a” 관계를 나타냄. 예: Car 클래스는 Vehicle 클래스의 일종임.
유연성:
의존성 주입: 객체의 의존성을 쉽게 교체할 수 있으며, 테스트가 용이함. 예를 들어, Engine 클래스의 다른 구현체를 주입하여 테스트할 수 있음.
상속: 클래스 계층 구조가 깊어질수록 유연성이 떨어질 수 있음. 상속은 다중 상속을 지원하지 않으므로, 한 클래스가 여러 클래스를 상속받을 수 없음.