본문 바로가기

Front-End/TypeScript

TypeScript #5 (클래스)

반응형

 

예문

class Person2 {
  constructor(public name: string, public age?: number) {}
}
let jack2: Person2 = new Person2('Jack', 32)
console.log(jack2)

 

 

생성자

- 객체를 초기화 하는 기능

- 생성자를 통해 전달된 값들이 객체의 속성으로 자동 할당

class Person2 {
  constructor(public name: string, public age?: number) {}
}

※ constructor : 클래스가 인스턴스화(클래스로부터 객체가 만들어지는 것)될 때 실행되는 함수

 

 

 

매개변수 속성

- 굳이 속성을 일일이 만들어서 호출해오지 않고, public을 붙여서 속성을 매개변수로 만듦.

// 일반적인 방법 (길고 반복적)
class Person1 {
  name: string;
  age?: number;
  
  constructor(name: string, age?: number) {
    this.name = name;
    this.age = age;
  }
}

 

위 코드는 아래 코드와 같다. 

// 매개변수 속성 사용 (간단함)
class Person2 {
  constructor(public name: string, public age?: number) {}
}

 

접근 제한자

 

  • public: 클래스 외부에서도 접근 가능 (기본값)
  • private: 클래스 내부에서만 접근 가능
  • protected: 클래스와 하위 클래스에서만 접근 가능

※ protected ?

  • 상속 계층에서의 공유: 부모 클래스의 내부 구현을 자식 클래스에서만 접근할 수 있게 함
  • 캡슐화 유지: 외부에서는 숨기면서 상속받은 클래스에서는 활용 가능
  • 템플릿 메서드 패턴: 부모 클래스에서 기본 구조를 제공하고 자식 클래스에서 세부 구현

 

class Person3 {
  constructor(
    public name: string,      // 외부 접근 가능
    private ssn: string,      // 클래스 내부에서만 접근
    protected id: number      // 클래스와 상속받은 클래스에서 접근
  ) {}
}

 

※ 변수에 '?'를 붙여 값을 받지 않아도 되게끔 할 수 있음.

 

 

 

 

인터페이스 

- 객체의 구조를 정의하는 규약, 클래스 몸통에 반드시 인터페이스가 정의하고 있는 속성을 멤버 속성으로 포함

- 타입 안정성, 코드 일관성 때문에 쓴다고 한다.

interface IPerson4 {
  name: string,
  age?: number
}

// IPerson4 규칙을 따르는 객체만 받을게~
class Person4 implements IPerson4 {
  constructor(public name: string, public age?: number) {}
}
let jack4: IPerson4 = new Person4('Jack', 32)

// implements : 오케이, 규약을 따르겠습니다! 맞는 속성으로 드릴게요!

 

 

 

추상 클래스

- 공통 기능 구현, 강제 구현

- 일관된 구조 강제

 

1. 직접 인스턴스 생성 불가

abstract class AbstractPerson5 {
  abstract name: string
  constructor(public age?: number) {}
}

// ❌ 에러 발생!
let person = new AbstractPerson5(25); // 추상 클래스는 인스턴스를 만들지 못함.

 

2. 반드시 상속 받아서 사용

class Student extends AbstractPerson5 {
  name: string; // 추상 속성을 반드시 구현해야 함
  
  constructor(name: string, age?: number) {
    super(age); // 부모 생성자 호출
    this.name = name;
  }
}

// ✅ 이제 사용 가능
let student = new Student('김학생', 20);
console.log(student.name); // '김학생'
console.log(student.age);  // 20

 

구조를 강제하는 가이드라인이라고 보면 될 듯?

 

 

 

※ 인터페이스 vs 추상 클래스

 

언제 쓰는 게 좋을까?

 

 

 

 

 

상속

- 부모 클래스에서 기능을 물려받을 때 사용.

- 부모의 특징을 물려받으면서 자신만의 특징을 추가하는 것이라는 느낌으로 이해.

// 부모 클래스 (기본 기능)
class Animal {
  name: string;
  age: number;
  
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
  
  eat() {
    console.log(`${this.name}이(가) 음식을 먹습니다.`);
  }
  
  sleep() {
    console.log(`${this.name}이(가) 잠을 잡니다.`);
  }
}

// 자식 클래스 (부모 기능 + 추가 기능)
class Dog extends Animal {
  breed: string; // 강아지만의 속성
  
  constructor(name: string, age: number, breed: string) {
    super(name, age); // 부모 생성자 호출
    this.breed = breed;
  }
  
  // 강아지만의 메서드
  bark() {
    console.log(`${this.name}: 멍멍!`);
  }
  
  // 부모 메서드 재정의(오버라이드)
  eat() {
    console.log(`${this.name}이(가) 사료를 먹습니다.`);
  }
}

 

  • extends: 상속받는다는 의미
  • super(): 부모 클래스의 생성자나 메서드 호출
  • 오버라이드: 부모 메서드를 자식에서 다시 정의
  • protected: 자식 클래스에서 접근 가능한 속성

 

 

 

static 속성

- 클래스 자체에 속함. (속성 or 메서드)

- 인스턴트 생성 불필요.

 

일반 속성과의 비교

 

언제 써야할까?

 

 

 

 

 

반응형