Skip to content

Latest commit

 

History

History
270 lines (223 loc) · 6.6 KB

2. 인터페이스와 클래스.md

File metadata and controls

270 lines (223 loc) · 6.6 KB

인터페이스와 클래스

  • 복잡한 구조를 가지고있는 애플리케이션을 작성할 때 좋다.

인터페이스와 타입 별칭 비교

  • 인터페이스 타입을 선언하는 문법은 객체 타입의 별칭을 만드는 문법과 비슷하다.
  • 인터페이스는 type을 사용하여 일기 쉬운 오류 메세지, 더 빠른 컴파일러 성능, 클래스와 함께 사용할 수 있는 장점을 제공한다.

type과 interface의 차이점

type interface
기존 타입 또는 새 타입을 생성하는 데 사용 객체 타입의 구조를 정의하는 데 사용
다른 타입 또는 인터페이스를 상속하거나 구현할 수 없음 다른 인터페이스를 상속하거나 구현할 수 있음
리터럴 타입, 유니온 타입, 인터섹션 타입을 사용할 수 있음 extends 키워드로 인터페이스 확장이 가능
간단한 타입 별칭을 생성할 때 적합 잘 정의된 구조의 객체 타입을 정의할 때 적합

예제

type BookType = {
    title: string;
    price: number;
    author: string;
};

interface Book {
    title: string;
    price: number;
    author: string;
};

let bookType: BookType = {
    title: "백엔드 개발자 되기",
    price: 10000,
    author: "박승규",
};

let book: Book = {
    title: "백엔드 개발자 되기",
    price: 10000,
    author: "박승규",
};

인터페이스의 선택적 속성과 읽기 전용 속성

선택적 속성

interface Car {
    name: string;
    price: number;
    brand: string;
    options?: string[]; //선택적 속성
}

let avante: Car = {
    name: "아반떼",
    price: 1500,
    brand: "현대",
    options: ["에어컨", "네비게이션"],
};

let morning: Car = {
    name: "모닝",
    price: 650,
    brand: "기아",
};

읽기 전용 속성

interface Citizen {
    id: string;
    name: string;
    readonly age: number;
}

let black: Citizen = {
    id: "1",
    name: "블랙",
    age: 25,
};

black.age = 20; //읽기 전용이므로 오류발생

인터페이스 확장하기

  • 비슷한 속성을 가진 인터페이스를 여러개 만들게 되는 상황일때 공통 속성을 가진 인터페이스를 상속받아 사용하면 편리하다
interface WebtoonCommon {
    title: string;
    createDate: Date;
    updateDate: Date;
}

interface Episode extends WebtoonCommon {
    episodeNumber: number;
    seriesNumber: number;
}

interface Series extends WebtoonCommon {
    seriesNumber: number;
    author: string;
}

const episode: Episode = {
    title: "똑 닮은 딸 1화",
    createDate: new Date(),
    updateDate: new Date(),
    episodeNumber: 1,
    seriesNumber: 123,
}

const series: Series = {
    title: "똑 닮은 딸 1화",
    createDate: new Date(),
    updateDate: new Date(),
    seriesNumber: 123,
    author: "작가님",
}

인터페이스 병합

  • 같은 인터페이스가 여러개 있으면 에러가 발생하는 것이 아니라 내부적으로 병합을 해준다.
interface Clock {
    time: Date;
}

interface Clock {
    brand: string;
}

interface Clock {
    price: number;
}

const wrongClock: Clock = { //brand, price 속성이 없어서 에러
    time: new Date(),
};

const clock: Clock = {
    time: new Date(),
    brand: "롤렉스",
    price: 1000,
};

클래스의 메서드와 속성

  • 자바스크립트에 클래스가 추가된것은 ES2015
  • 타입스크립트는 클래스를 완벽하게 지원함
class Hello {
    constructor() { //생성자 메서드
        this.sayHello("create");
    }
    
    sayHello(message: string) {
        console.log(message);
    }
}

const hello = new Hello();
hello.sayHello("안녕하세요!");
=> create
=> 안녕하세요!
  • 클래스 명은 기본적으로 파스칼케이스를 따르되 첫글자를 대문자로 쓴다.
  • 생성자는 매개변수가 있을 수 도, 없을 수 도 있다.
  • 클래스 내부의 메스드에서 클래스 속성에 접글할 때는 this.<변수명> 형식을 사용한다.

인터페이스로 구현한 클래스

  • 클래스에서 인터페이스를 상속할때 implements 키워드를 사용
  • 클래스에서 반드시 선언해야하는 속성과 메서드를 강제할 수 있다.
interface IClicker {
    count: number;
    click():number;
}

class Clicker implements IClicker {
    //인터페이스에 기재된 내용을 작성하지 않으면 에러 발생
    count: number = 0;
    
    click(): number {
        this.count += 1;
        console.log(`Click! [count] : ${this.count}`);
        
        return this.count;
    }    
}

const clicker = new Clicker();
clicker.click();    // Click! [count] : 1
clicker.click();    // Click! [count] : 2
clicker.click();    // Click! [count] : 3
clicker.click();    // Click! [count] : 4

추상 클래스

  • abstract 키워드를 사용하여 추상 클래스, 메서드를 생성
  • 추상 클래스에서만 추상메서드를 만들 수 있음
  • 대부분의 코드가 비슷하지만, 특정 부분만 다르게 구현하는 클래스를 여러개 작성할 때 유용함
abstract class Logger {
    prepare() {
        console.log("===========");
        console.log("로그 준비");
    }

    log(message: string) {
        this.prepare();
        this.execute(message);
        this.complete();
    }

    abstract execute(message: string): void;

    complete() {
        console.log("완료");
        console.log("");
    }
}

class FileLogger extends Logger {
    filename: string;

    constructor(filename: string) {
        super();
        this.filename = filename;
    }
    
    execute(message: string) {
        console.log(`[${this.filename}] > ${message}`);
    }  
}

class ConsoleLogger extends Logger {
    execute(message: string) {
        console.log(message);
    }
}

const fileLogger = new FileLogger("test.log");
fileLogger.log("파일에 로그 남기기");

const consoleLogger = new ConsoleLogger();
consoleLogger.log("로그 남기기");
===========
로그 준비
[test.log] > 파일에 로그 남기기
완료

===========
로그 준비
로그 남기기
완료

클래스의 접근 제어자

  • 클래스 내의 변수와 메서드에는 접근제어자인 public, protected, private를 사용할 수 있다.
  • public : 모든곳에서 접근 가능(기본값)
  • protected : 클래스 내부 혹은 자녀 클래스만 접근 가능
  • private : 클래스 내부에서만 접근 가능