✅ 1단계: 클래스와 객체 만들기
※ 목표: 클래스를 만들고 객체를 생성해보기
▶ Person이라는 클래스를 만들고, 이름(name)과 나이(age)를 속성으로 가진 후,
introduce() 메서드를 만들어 "안녕하세요, 저는 20살의 Alice입니다."와 같은 문장을 출력
class Person { // Person 클래스 생성 : name 속성, age 속성
name: string;
age: Number;
introduce() { // 클래스 안에서 지정한 속성 사용 - this.속성
console.log(`안녕하세요, ${this.age}살의 ${this.name}입니다.`)
}
}
// Person 클래스의 객체(인스턴스) 생성
let person = new Person();
person.age = 22;
person.name = "Alice";
// 생성된 객체에서 클래스 내 메소드 호출
person.introduce();

✅ 2단계: 생성자(Constructor) 사용
※ 목표: 생성자를 통해 속성 초기화 연습
▶ Product 클래스를 만들고, 생성자를 통해 name과 price를 입력받아 초기화하기.
그리고 display()라는 메서드를 만들어 "제품명: MacBook, 가격: 150만원"을 출력하기.
class Product { // Product 클래스 생성
// 생성자에서 클래스 name, price 속성 설정
constructor(public name: string, public price: number) {}
// 클래스 내의 속성들을 이용한 display 메소드 생성
display() {
console.log(`제품명: ${this.name}, 가격: ${this.price/10000}만원`)
}
}
// Product 클래스의 객체 생성, 속성값 import
let product = new Product("MacBook", 1500000);
// 생성된 객체에서 display 메소드 호출
product.display();

✅ 3단계: 접근 제한자 (캡슐화)
※목표: private 속성 사용해보기
▶ BankAccount 클래스를 만들고, #balance(잔액)를 private 속성으로 선언하기.
deposit(amount: number)와 getBalance() 메서드를 구현해 입금 및 조회 기능을 제공하기
class BankAccount { // BankAccount 클래스 생성
// 계좌 잔고 설정 - private
private balance: number = 100; // #속성 : 속성을 private로 선언, 최신 버전에서만 인식
deposit(amount: number) { // amount를 속성으로 갖는 예금 메서드 생성
this.balance += amount; // 예금 액수 만큼 잔고에 추가하는 기능
}
getBalance() { // 계좌 잔고를 확인하는 메서드
console.log(`${this.balance}원`); // 클래스 내의 속성을 이용 (this.balance)
}
setBalance(amount: number) { // private 속성에는 setter가 필요
amount = amount * 1.1; // 금리 기능 추가. 예금 액수에 10% 가산
this.balance = amount; // 금리가 적용된 최종 금액을 계좌 잔고로 업데이트
}
}
// BankAccount 클래스의 객체 생성
let account = new BankAccount();
// 생성된 객체에서 금액 1만원 예금
account.setBalance(10000);
// 계좌 잔고 확인
account.getBalance();

✅ 4단계: 상속(Inheritance)
※ 목표: 클래스를 상속해서 기능 확장하기
▶ Animal 클래스를 만들고 sound() 메서드를 정의하기.
Dog, Cat 클래스를 Animal로부터 상속받아 각각 "멍멍!", "야옹!"을 출력하도록 오버라이딩하기
class Animal { // Animal 클래스 생성 (부모 클래스)
animal: string; // 클래스에서 받을 animal 속성 설정
sound() { // 동물이 짖는 메소드 생성
console.log("!!!")
}
}
// Animal 클래스에게 상속 받는 Doggo 클래스 생성 (자식 클래스, extends 사용)
class Doggo extends Animal {
sound() { // bark 메소드 생성 (오버라이딩)
console.log("멍멍!")
}
}
// Animal 클래스에게 상속 받는 Kitty 클래스 생성 (자식 클래스, extends 사용)
class Kitty extends Animal {
sound() { // meow 메소드 생성 (오버라이딩)
console.log("야옹!")
}
}
// 각각의 자식 클래스로부터의 객체 생성
let doggo = new Doggo();
let kitty = new Kitty();
// 생성된 각각의 객체에서 메소드 호출
doggo.sound();
kitty.sound();

✅ 5단계: 다형성(Polymorphism)
※ 목표: 하나의 타입으로 여러 객체 다루기
▶ 위에서 만든 Animal 클래스를 이용해 const animals: Animal[] = [new Dog(), new Cat()] 배열을 만들고,
반복문을 통해 sound()를 호출하여 각각의 소리를 출력하기.
// 4단계에서 만든 animal.ts, 원본 파일에서 각 클래스에 export를 붙여 모듈화
export class Animal {
...
}
export class Doggo extends Animal {
...
}
export class Kitty extends Animal {
...
}
...
// 4단계에서 호출한 라인들은 모두 주석 처리 !
// // 생성된 각각의 객체에서 메소드 호출
// doggo.bark();
// kitty.meow();
import { Animal, Doggo, Kitty } from "./animal"; // 원본 파일로부터 모듈화된 각 클래스 호출
// animals 변수에 Animal이라는 배열 만들어서 배열 안에 Doggo와 Kitty 클래스의 객체들 넣기
const animals: Animal[] = [new Doggo(), new Kitty()];
// 반복문으로 각 동물의 소리 출력
// 같은 sound() 메소드를 호출하지만, 각 객체의 실제 타입에 따라 다른 소리가 출력
animals.forEach(animal => {
animal.sound(); // 다형성! 같은 메소드명이지만 다른 결과
});

✅ 6단계: 추상 클래스(Abstract)
※ 목표: 공통 구조 정의와 구현 강제화
▶ Shape라는 추상 클래스를 만들고, getArea(): number 추상 메서드를 정의하기
Rectangle, Circle 클래스를 상속받아 각각 면적을 계산하는 로직을 구현하기
abstract class Shape { // abstract로 추상 클래스 생성
size: number;
// calculateArea() {
// return 1;
// }
// 추상 클래스 안에 있는 메서드도 무조건 추상 abstract 붙여야 함
// 이 클래스를 상속 받는 자식 클래스에서 "필수로 설정"해야할 메서드를 선언
abstract getAreaRectangle(width: number, height: number): number;
abstract getAreaCircle(radius: number): number;
}
// 부모 클래스를 상속 받는 자식 클래스에서 추상 메서드를 구체적으로 설계
class Rectangle extends Shape {
getAreaRectangle(width: number, height: number): number {
return width * height;
}
// 다른 추상 클래스에 대해서는 예외처리 해야함. 에러 출력
getAreaCircle(radius: number): number {
throw Error("Unimplemented method")
}
}
class Circle extends Shape {
getAreaCircle(radius: number): number {
return radius ** 2 * Math.PI
}
getAreaRectangle(width: number, height: number): number {
throw Error("Unimplemented method")
}
}
※ 오류를 출력하는 메서드를 호출할 경우.

✅ 7단계: 인터페이스(Interface)
※ 목표: 객체의 형태를 정의하고 클래스에 구현
▶ Movable이라는 인터페이스를 만들고 move(): void 메서드를 포함시키기.
Car, Robot 클래스에 이 인터페이스를 구현하고 각각 다르게 move()를 정의하기.
interface Moveable { // 특정 클래스들에게 꼭 지켜야 하는 규약 설정, 타입 정리할 때 많이 씀
move(): void;
}
// 클래스에 implements를 넣어 해당 인터페이스를 따름
class Car0 implements Moveable {
move(): void {
console.log("car");
}
}
class Robot implements Moveable {
move(): void {
console.log("robot");
}
}
✅ 8단계: 메서드 오버로딩
※ 목표: 하나의 메서드 이름으로 다양한 인자 처리
▶ Calculator 클래스를 만들고 add() 메서드를 오버로딩하여 숫자 2개를 더할 수 있도록 하고,
문자열 2개도 연결할 수 있도록 구현하기
class Calculator {
add(a: number, b: number): void {
console.log(a + b);
}
add(a: string, b: number): void {
console.log(a + b);
}
}
let calculator = new Calculator();
calculator.add(1, 2);
calculator.add("1", "2");
✅ 9단계: 정적 속성/메서드 (static)
※ 목표: 클래스 소속 메서드와 속성 다루기
▶ Counter 클래스를 만들고 모든 객체가 공유하는 count 값을 가지게 하기
increment()를 호출할 때마다 count가 1씩 증가하도록 하기. getCount() 메서드로 현재 값을 출력
class Counter {
static count: number = 0;
static increment() {
Counter.count++;
}
static getCount() {
console.log(Counter.count);
}
}
// 인스턴스(객체) 생성 없이 사용 가능
// 클래스 이름으로 직접 접근
// 모든 곳에서 같은 값 공유
Counter.increment();
Counter.increment();
Counter.increment();
Counter.getCount();

✅ 10단계: 종합 실습 프로젝트 (간단한 주문 시스템)
※ 목표: 객체지향 종합 적용
User, Product, Order 클래스를 만들어
사용자 User가 제품 Product를 주문하여 Order를 생성하고
Order 클래스에 summary() 메서드를 만들어 "사용자 A가 상품 B를 구매했습니다."를 출력하세요.
// 주문 시스템은 그림을 그리든 ERD를 그리든 그려서 이해하는 게 더 빠르다.
class User0 { // 이용자, 고객 클래스
userName: string;
}
class Product { // 제품, 상품 클래스
productName: string;
}
class Order { // 주문 클래스 (고객과 상품을 받음)
user: User0;
product: Product;
summary() { // 다른 클래스에서 받은 속성들을 이용하여 로그 출력
console.log(`사용자 ${this.user.userName}이(가) 상품 ${this.product.productName}을 주문했습니다.`)
}
}
// 각 클래스의 객체 생성
let user1 = new User0();
user1.userName = "홍길동"
let product1 = new Product();
product1.productName = "책"
// 주문 클래스의 객체는 생성할 때 다른 클래스의 속성을 호출
let order1 = new Order();
order1.user = user1;
order1.product = product1;
// 주문 객체에서의 메서드 호출
order1.summary();

'Front-End > TypeScript' 카테고리의 다른 글
| TypeScript #14 (제네릭) (0) | 2025.07.04 |
|---|---|
| TypeScript #12 (OOP 예제 #1~5) (0) | 2025.07.03 |
| TypeScript #11 (객체 지향) (0) | 2025.07.03 |
| TypeScript #10 (함수 유효성 검사) (0) | 2025.07.02 |
| TypeScript #9 (함수) (0) | 2025.07.02 |