다재다능 개발자 성장기 🚀
TypeScript - 5주차(객체 지향 프로그램) 본문
클래스와 객체
클래스란?
- 클래스는 객체 지향 프로그래밍(OOP)의 핵심 구성 요소 중 하나이다.
- 클래스는 객체를 만들기 위한 틀이다.
클래스의 구성요소
- 클래스에서는 같은 종류의 객체들이 공통으로 가지는 속성과 메서드를 정의한다.
- 속성은 객체의 성질을 결정하는 것이다.
- 예를 들어, 붕어빵은 '팥'이란 속성이 있는 팥 붕어빵과 '슈크림'이란 속성이 있는 슈크림 붕어빵이 있다.
- 메서드는 객체의 성질을 변화시키거나 객체에서 제공하는 기능들을 사용하는 창구이다.
- 붕어빵 주인은 붕어빵을 팥 붕어빵에서 슈크림 붕어빵으로 전환할 수 있다.
- 붕어빵을 사는 고객들은 팥 붕어빵, 슈크림 붕어빵의 가격을 알 수 있다.
객체란?
객체는 클래스를 기반으로 생성되며 클래스의 인스턴스(instance)라고도 한다.
클래스 정의하기
- TypeScript에서 클래스를 정의하려면 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)
- 생성자는 클래스의 인스턴스를 생성하고 초기화하는데 사용되는 특별한 메서드이다.
- 생성자는 클래스 내에서 constructor라는 이름으로 정의된다.
- 생성자는 인스턴스를 생성할 때 자동으로 호출된다.
- 생성자는 클래스 내에 오직 하나만 존재할 수 있다.
- 보통, 생성자로 객체 속성을 초기화 하는 것 뿐 아니라 객체가 생성이 될 때 꼭 되어야 하는 초기화 로직을 집어넣기도 한다.
- 예를들어, DBConnector라는 클래스가 있다면 이 클래스 타입의 객체가 생성이 될 때 생성자에서 DB 연결을 미리 해주면 편하다.
클래스 접근 제한자
접근 제한자
- 클레스에서는 속성과 메서드에 접근 제한자를 사용해 접근을 제한할 수 있다.
- TypeScript에서는 다음의 접근 제한자들을 제공한다.
public
- 클래스 외부에서도 접근이 가능한 접근 제한자이다.
- 접근 제한자가 선언이 안되어있다면 기본적으로 접근 제한자는 public이다.
- 보통은 클래스의 함수 중 민감하지 않은 객체 정보를 열람할 때나 누구나 해당 클래스의 특정 기능을 사용해야 할 때 많이 쓰인다.
private
- 클래스 내부에서만 접근이 가능한 접근 제한자이다.
- 보통은 클래스의 속성은 대부분 private으로 접근 제한자를 설정한다.
- 즉, 외부에서 직접적으로 객체의 속성을 변경할 수 없게 제한하는 것이다.
- 클래스의 속성을 보거나 편집하고 싶다면 별도의 getter/setter 메서드를 준비해 놓는 것이 관례이다.
protected
클래스 내부와 해당 클래스를 상송받은 자식 클래스에서만 접근이 가능한 접근 제한자이다.
사용사례
class Person {
private name: string;
private age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
public sayHello() {
console.log(`안녕하세요! 제 이름은 ${this.name}이고, 나이는 ${this.age}살입니다.`);
}
}
상속
상속이란?
- 상속은 객체 지향 프로그램에서 클래스 간의 관계를 정의하는 중요한 개념이다.
- 상속을 통해 기존 클래스의 속성과 메서들르 물려받아 새로운 클래스를 정의할 수 있다.
- 상속이 있어서 똑같은 코드를 계속 반복적으로 작성할 필요가 없게 된다.
- 상속을 구현하려면 extends 키워드를 사용하면 된다.
사용예시
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('멍멍!'); // 부모의 makeSound 동작과 달라요!
}
eat() { // Dog 클래스만의 새로운 함수 정의
console.log('강아지가 사료를 먹습니다.');
}
}
class Cat extends Animal { // Animal과 다를게 하나도 없어요!
}
const dog = new Dog('누렁이');
dog.makeSound(); // 출력: 멍멍!
const cat = new Cat('야옹이');
cat.makeSound(); // 출력: 동물 소리~
- 여기서 Animal을 부모 클래스, Dog을 자식 클래스라고 한다.
- super 키워드는 자식 클래스가 부모 클래스를 참조하는 데 사용하는 키워드이다.
- 즉, 자식 클래스에서 생성자를 정의할 때 부모 클래스의 생성자를 호출해야 하는데 이 때 사용한다.
- 자식 클래스가 부모 클래스의 생성자나 메서드를 그대로 사용하고 싶다면 자식 클래스에선 다시 작성하지 않아도 된다.
- Dog 클래스는 부모의 makeSound 함수의 동작을 새롭게 정의한다. 이것을 오버라이딩이라고한다.
객체지향 설계 원칙(S.O.L.I.D)
- 단일 책임 원칙(SRP)
- 한 클래스는 하나의 책임만 가져야 한다.
- 개발 폐쇄 원칙(OCP)
- 확장에는 열려 있고 수정에는 닫혀 있어야 한다.
- 리스코프 치완 원칙(LSP)
- 서브타입은 슈퍼타입을 대체할 수 있어야 한다.
- 인터페이스 분리 원칙(ISP)
- 인터페이스는 클라이언트가 필요로 하는 메서드만 제공해야 한다.
- 의존성 역전 원칙(DIP)
- 추성화에 의존해야 하며 구체화에 의존하면 안된다.
'TIL ⭐' 카테고리의 다른 글
TypeScript - 4주차(유틸리티 타입 훑어보기) (0) | 2024.08.23 |
---|---|
TypeScript - 4주차(enum과 object literal) (0) | 2024.08.23 |
TypeScript - 3주차(타입의 종류 2) (0) | 2024.08.17 |
TypeScript - 3주차(타입의 종류 1) (0) | 2024.08.17 |
TypeScript - 3주차(변수) (0) | 2024.08.17 |