본문 바로가기

TYPESCRIPT

[타입스크립트] 객체지향 클래스

타입스크립트 vs 자바스크립트 

타입스크립트에서 작성한 코드가 자바스크립트로 컴파일 되는 것을 보면, private 혹은 property를 생성해줌 

타입스크립트와 객체지향이 가지고 있는 훌륭한 것은 추상클래스 (abstract class) 

자바스크립트와 달리 타입스크립트에서는 this.이름 =이름 를 사용해 직접 적지 않는 대신에, 필드의 접근제어자, 이름, 타입을 작성함 

 

추상 클래스 

다른 클래스가 상속받을 수 있는 클래스 

추상 클래스로 직접 새로운 인스턴스를 만들 수는 없음 (타입스크립트가 방지)

추상 클래스 안에서 추상 메소드를 만들 수 있음 (메소드 구현 대신 메소드의 call signiture만 작성) 

 

※ 접근 제어자 작성법 

접근 제어자 구분 선언 클래스 내 상속 클래스 내 인스턴스
 private o x
protected  o o x
public  o o o

추상 메소드 

구현이 되어있지 않은(코드가 없는)메소드    call signiture 로 표현 

추상 클래스를 상속받는 클래스들이 추상 메소드를 구현함 


해시맵 단어 사전 ( 추가 / 삭제 / 수정 / 출력  / 불러오기 ) 

nomard 강의 참고 

// 객체의 타입 선언 
type Words = {
    // Words의 타입이 string 인 것만 알고, 프로퍼티의 이름은 모를 때
    [key:string] : (string|string[])
}

// 사전 클래스 생성 
class Dict {
    private words : Words // words를 initializer로 선언 
    constructor() {
        this.words = {} // 초기화
    }

    // 사전 추가 : 클래스를 타입처럼 사용가능
    add(word:Word) {
        if(this.words[word.term] === undefined) {
            this.words [word.term] = word.def; 
        }
    }

    // 단어 찾기 
    find(term :string){
        return this.words[term]; 
    }

    // 단어 삭제 
    remove(rerm :string) {
        delete this.words[term]; 
    }

    // 단어 업데이트
    update(oldTerm :string, newTerm :string){
        if(this.words.hasOwnProperty(oldTerm)){
            this.words[newTerm] = this.words[oldTerm];

            delete this.words[oldTerm]; 
        }
    }

    // 사전 저장된 단어 개수 
    count(){
        return Object.keys(this.words).length;
    }

    // 모든 사전 출력
    allPrint() {
        for(let [key,value] of Object.entries(this.words)){
            console.log(`${key}:${value}`)
        }
    }
}


// 각각의 단어에 대한 클래스 
//  Word는 initializer없이 선언해주고 constructor에서 수동으로 초기화
// constructor에 인자로 넣어서 constructor가 지정해주길 바라는게 아님
class Word {
    constructor (
        public term :string,
        public def :(string |string[])){}
    
    //단어 출력 메소드 
    toString(){
        console.log(`${this.term} : ${this.def}`);
    }


    // 단어 정의 추가
    addDef(newDef:string){
        if(typeof this.def === 'string'){
            this.def = [this.def, newDef]
        }else {
            this.def = [...this.def, newDef];
        }
    }

    // 단어 정의 수정 
    updateDef(oldDef:string, newDef :string) {
        if (typeof this.def === 'string'){
            if(oldDef === this.def) this.def = newDef
        }else {
            this.def.filter(val => val !== oldDef);
            this.def.push(newDef); 
        }
    }
}

// 출력하기
const kimchi = new Word ("kimici","한국의 음식");
 
 const dict = new Dict()
 
 kimchi.addDef("배추와 고추가루 양념을 버무려 발효한 음식");
 kimchi.toString(); // kimchi : 한국의 음식 , 배추와 고추가루 양념을 버무려 발효한 음식
 
 dict.allPrint()
 // kimchi : 한국의 음식 , 배추와 고추가루 양념을 버무려 발효한 음식
 
 dict.count() // 1
 dict.find("kimchi"); //) ['한국의 음식', '고춧가루로 배추를 버무려 숙성 및 발효시킨 음식']
 
 dict.update("kimchi", "김치")
 // 김치 : 한국의 음식, 고춧가루로 배추를 버무려 숙성 및 발효시킨 음식
 
dict.remove("김치"); 
dict.allPrint(); // null

 

728x90