(1) 클래스란?
클래스는 객체 지향 프로그래밍(OOP)의 핵심 구성 요소 중 하나로, 객체를 만들기 위한 틀(템플릿)이다.
(2) 클래스 정의 방법
class
키워드를 사용하여 클래스 정의new
키워드를 사용하여 객체 생성
class Person {
name: string;
age: number;
// 생성자
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
sayHello() {
console.log(`안녕하세요! 제 이름은 ${this.name}이고, 나이는 ${this.age}살입니다.`);
}
}
const person = new Person('Spartan', 30);
person.sayHello();
constructor
(3) 클래스 접근 제한자
(1) 상속이란?
상속은 객체 지향 프로그래밍에서 클래스 간의 관계를 정의하는 중요한 개념으로,
상속을 통해 기존 클래스의 속성과 메서드를 물려받아 새로운 클래스를 정의할 수 있다.
extends
키워드 사용super
부모 클래스의 생성자 호출- 오버라이딩 : 부모의 함수 동작을 새롭게 정의하는 것
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
makeSound() {
console.log('동물 소리~');
}
}
// 상속
class Dog extends Animal {
age: number;
constructor(name: string) {
super(name);
this.age = 5;
}
makeSound() {
console.log('멍멍!'); // 오버라이딩(함수의 동작을 새롭게 정의)
}
eat() {
console.log('강아지가 사료를 먹습니다.'); // Dog 클래스만의 새로운 함수 정의
}
}
class Cat extends Animal { // Animal과 동일한 속성으로 생성
}
const dog = new Dog('누렁이');
dog.makeSound(); // 출력: 멍멍!
const cat = new Cat('야옹이');
cat.makeSound(); // 출력: 동물 소리~
(2) 서브타입, 슈퍼타입
서브타입 / 슈퍼타입
위 예시에서 animal은 슈퍼타입, dog, cat은 서브타입
upcasting : 서브타입 → 슈퍼타입으로 변환
let dog: Dog = new Dog('또순이');
let animal: Animal = dog; // 슈퍼타입 변수에 대입하여 upcasting
animal.eat(); // 에러. 슈퍼타입(Animal)으로 변환이 되어 eat 메서드 호출 불가능
let animal: Animal;
animal = new Dog('또순이');
let realDog: Dog = animal as Dog; // as로 명시적으로 타입 변환
realDog.eat(); // 서브타입(Dog)로 변환이 되었기 때문에 eat 메서드 호출 가능
인스턴스화를 할 수 없는( new 로 객체를 생성할 수 없는) 클래스
abstract
키워드를 사용하여 정의// 추상 클래스 정의
abstract class Shape {
abstract getArea(): number; // 추상 함수 정의(자식 클래스에서 핵심 기능 구현)
printArea() {
console.log(`도형 넓이: ${this.getArea()}`);
}
}
// 자식 클래스
class Circle extends Shape {
radius: number;
constructor(radius: number) {
super();
this.radius = radius;
}
getArea(): number { // 자식 클래스에서 필수로 구현해야 함
return Math.PI * this.radius * this.radius; // 원의 넓이를 구하는 공식
}
}
→ 각 도형마다 넓이를 구하는 공식이 다르기 때문에, 각각의 자식 클래스에서 핵심 기능을 구현
(1) 인터페이스란?
객체가 가져야 하는 속성과 메서드를 정의한다.
인터페이스를 사용하면 코드의 안정성과 유지 보수성을 향상시킬 수 있다.
(2) 추상 클래스와 인터페이스의 차이
추상클래스 | 인터페이스 | |
---|---|---|
구현부 제공 여부 | 클래스의 기본 구현 제공 | 객체의 구조만 정의 |
상속 메커니즘 | 단일 상속 지원 | 다중 상속 지원 |
구현 메커니즘 | 추상 클래스를 상속받은 자식클래스는 반드시 추상함수 구현 | 인터페이스를 구현하는 클래스는 정의된 모든 메서드 전부 구현 |
(1) S(SRP. 단일 책임 원칙)
클래스는 하나의 책임만 가져야 하며, 다른 액션을 해서는 안된다.
(2) O(OCP. 개방 폐쇄 원칙)
클래스의 기존 코드를 변경하지 않고도 기능을 확장할 수 있어야 하며, 수정에 대해서는 닫혀 있어야 한다. → 인터페이스나 상속을 통해 해결
(3) L(LSP. 리스코프 치환 원칙)
서브타입은 기반이 되는 슈퍼타입을 대체할 수 있어야 한다.
자식 클래스는 부모 클래스의 기능을 수정하지 않고도 부모 클래스와 호환이 되어야 한다.
(4) I(ISP. 인터페이스 분리 원칙)
클래스는 자신이 사용하지 않는 인터페이스의 영향을 받지 않아야 한다.
인터페이스를 필요한 만큼만 정의하고, 클래스는 필요한 인터페이스들을 구현한다.
(5) D(DIP. 의존성 역전 원칙)
하위 수준 모듈(구현 클래스)보다 상위 수준 모듈(인터페이스)에 의존해야 한다.
TypeScript 강의를 5주차까지 다 들었는데, 개념이 너무 헷갈린다. type, class, interface 각각 차이가 아직 명확하게 머릿속에 들어오지 않는다. 다양한 예제를 적용해봐야 좀 감이 잡힐 것 같다. 내일 과제를 해보면서 다시 개념을 정리 해봐야 할 것 같다. 어렵다...