능히 해낼 수 있다

230817 TypeScript: class 본문

개발🌐/TypeScript

230817 TypeScript: class

roni_eo 2023. 8. 15. 14:33
반응형

✍️✍️✍️ 위 글은 작성자의 지식습득에 따라 추후 퇴고 될 수 있음을 알려드립니다(피드백 환영).


 

230804 JavaScript: class

✍️✍️✍️ 위 글은 작성자의 지식습득에 따라 추후 퇴고 될 수 있음을 알려드립니다(피드백 환영). JavaScript에서 클래스는 ES6 (ECMAScript 2015)부터 도입되었다. 클래스는 객체 지향 프로그래밍의

ronieo.com

TypeScript class에 대해 알아보기 전에 JavaScript class관해 배경지식이 있으면 이해하는데 조금 더 도움 된다.


TypeScript 클래스는 JavaScript 클래스를 기반으로 확장된 기능을 제공하는 객체 지향 프로그래밍의 개념으로 TypeScript는 정적 타입 검사를 제공하여 JavaScript 코드를 보다 안정적으로 관리할 수 있도록 도와주며, 이를 활용하여 클래스를 작성하면 코드의 가독성과 유지보수성을 향상시킬 수 있다.

1. 클래스 선언과 생성

class Animal {
    // 속성 (멤버 변수)
    name: string;
    
    // 생성자 (Constructor)
    constructor(name: string) {
        this.name = name;
    }
    
    // 메서드
    makeSound() {
        console.log(`${this.name} makes a sound.`);
    }
}

// 객체 생성
const dog = new Animal("Dog");
dog.makeSound(); // 출력: "Dog makes a sound."

JavaScript와 거의 비슷하지만 차이점은 변수와 프롭스(매개변수)에 타입을 선언해 준다는 점에서 차이점이 있다. 그래서 name에는 string타입이 선언 되어 있다. 멤버변수의 타입선언을 하지않고 매개변수에 public이나 readonly(최초로 받은 값을 절대 수정할 수 없도록 만듦)키워드를 넣어서 타입을 선언하는 방법도 있다.


2. 접근제한자

TypeScript에서 세가지 주요 접근제한자를 지원하는데, 클래스의 속성와 메서드에 대한 접근범위를 지정하는 역할을 한다.

  • public: 기본값으로, 자식클래스, 클래스인스턴스 등 어디서든 접근 가능하다. 특별히 키워드가 없다면 public이라고 생각하면 된다.
  • protected: 클래스 내부 및 해당 클래스를 상속한 하위 클래스(자식 클래)에서만 접근 가능하고 외부에서 직접 접근 할 수 없다.
  • private: 해당 클래스 내부에서만 접근 가능하고, 클래스 외부에서는 접근할 수 없다. 표현하는 또다른 방법은 #으로 적을 수 있다. 표기법에 따른 기능상의 차이는 없다.
  • static: 정적 멤버 변수를 만들 수 있다. this가 아닌 클래스 명을 넣어서 부를 수 있다.
class Person {
    public name: string;
    protected age: number;
    private email: string;
    // 또는 #email: string;
    static position: string
    
    constructor(name: string, age: number, email: string) {
        this.name = name;
        this.age = age;
        this.email = email;
    }
}

class Employee extends Person {
    constructor(name: string, age: number, email: string) {
        super(name, age, email);
    }
    
    displayDetails() {
        console.log(`Name: ${this.name}, Age: ${this.age}`);
        // console.log(`Email: ${this.email}`); // private 속성에 접근할 수 없음
    }
}

const person = new Person("Mimi", 30, "mimi@example.com");
console.log(person.name); // 접근 가능
// console.log(person.age); // 클래스 인스턴스는 protected 속성에 접근할 수 없음
// console.log(person.email); // private 속성에 접근할 수 없음

const employee = new Employee("rosi", 25, "rosi@example.com");
employee.displayDetails(); // 출력: "Name: rosi, Age: 25"
//console.log(Person.position); 
// person이 아닌 클래스이름인 Person을 통해 클래스 자체의 static 속성에 접근 가능

2 - 1. super

super 키워드는 하위 클래스에서 부모 클래스의 생성자와 메서드에 접근하는 데 사용된다. 생성자 내에서 부모 클래스의 생성자를 호출할 때, 메서드 내에서 부모 클래스의 메서드를 호출할 때 사용한다.

  1. 생성자 내에서의 super: 하위 클래스의 생성자 내에서 super()를 호출하여 부모 클래스의 생성자를 실행한다. 이를 통해 하위 클래스에서 부모 클래스의 속성을 초기화할 수 있다.
  2. 메서드 내에서의 super: 하위 클래스의 메서드 내에서 super.methodName() 형태로 사용하여 부모 클래스의 메서드를 호출한다.
class Person {
    public name: string;
    protected age: number;
    private email: string;
    
    constructor(name: string, age: number, email: string) {
        this.name = name;
        this.age = age;
        this.email = email;
    }
    
    displayInfo() {
        console.log(`Name: ${this.name}, Age: ${this.age}`);
        // console.log(`Email: ${this.email}`); // private 속성에 접근할 수 없음
    }
}

class Employee extends Person {
    private position: string;
    
    constructor(name: string, age: number, email: string, position: string) {
        super(name, age, email); // 부모 클래스 생성자 호출
        this.position = position;
    }
    
    showInfo() {
        super.displayInfo(); // 부모 클래스의 displayInfo 메서드 호출
        console.log(`Position: ${this.position}`);
        // console.log(`Email: ${this.email}`); // private 속성에 접근할 수 없음
    }
}

const person = new Person("Mimi", 30, "mimi@example.com");
console.log(person.name); // 접근 가능
// console.log(person.age); // protected 속성에 접근할 수 없음
// console.log(person.email); // private 속성에 접근할 수 없음

const employee = new Employee("rosi", 25, "rosi@example.com", "Manager");
employee.displayInfo(); // 출력: "Name: rosi, Age: 25"
employee.showInfo();    // 출력: "Name: rosi, Age: 25", "Position: Manager"

위 코드에서 Employee 클래스의 생성자에서 super(name, age, email)를 호출하여 Person 클래스의 생성자를 실행하고, Employee 클래스의 showInfo 메서드에서 super.displayInfo()를 호출하여 Person 클래스의 displayInfo 메서드를 실행하고 있다. super 키워드를 사용하여 부모 클래스의 생성자와 메서드를 호출함으로써 상속 관계를 활용및 확장할 수 있다.


3. 추상클래스

추상 클래스는 abstract키워드를 사용한다. 직접 인스턴스화할 수 없으며, 하나 이상의 추상 메서드를 포함할 수 있다. 그래서 추상클래스를 이용해 new키워드로 객체를 생성할 순 없다. 
하지만 추상클래스를 상속받은 자식클래스에서 추상메서들르 구현한 후 그 자식 클래스로 객체생성이 가능하다.

추상 클래스의 주요 목적은 하위 클래스에 일부 메서드의 구현을 강제하는 것이다. 이를 통해 다형성을 구현하거나, 공통된 인터페이스를 제공하는 기반 클래스를 정의할 수 있다.

abstract class Shape { // 추상클래스
    abstract calculateArea(): number; // 추상메서드 선언: 직접 객체 생성 불가
}

class Circle extends Shape { // 추상클래스Shape를 상속 받은 하위클래스Circle
    radius: number;
    
    constructor(radius: number) {
        this.radius = radius;
    }
    
    calculateArea() { // 상속받은 추상클래스로 객채생성가능 + 구현강제
        return Math.PI * this.radius ** 2;
    }
}

class Triangle extends Shape { // 추상클래스Shape를 상속 받은 하위클래스Triangle
    base: number;
    height: number;
    
    constructor(base: number, height: number) {
        this.base = base;
        this.height = height;
    }
    
    calculateArea() { // 상속받은 추상클래스로 객채생성가능 + 구현강제
        return 0.5 * this.base * this.height;
    }
}

const circle = new Circle(5);
const triangle = new Triangle(10, 8);

console.log(circle.calculateArea());   // 출력: 78.53981633974483
console.log(triangle.calculateArea()); // 출력: 40

위 예시에서 Shape 추상 클래스를 상속받은 Circle 클래스와 Triangle 클래스는 calculateArea 메서드를 각각 구현하고 있다. 이렇게 다양한 하위 클래스를 만들어 동일한 메서드를 다르게 구현하도록 할 수 있다.

반응형

'개발🌐 > TypeScript' 카테고리의 다른 글

230822 TypeScript: 유틸리티 타입  (0) 2023.08.22
230822 TypeScript: 제네릭  (0) 2023.08.22
230815 TypeScript: 리터럴, 유니온, 교차 Type  (0) 2023.08.15
230815 TypeScript: 함수  (0) 2023.08.15
230811 TypeScript: Interface  (0) 2023.08.11