View

Constructor(생성자)

파라미터들을 써주기만 하면 TypeScript가 알아서 Constructor 함수를 만들어줌

class로부터 객체를 생성할 때 호출되고 객체의 초기화를 담당

  • TypeScript
class Player {
    constructor(
        private firstName:string,
        private lastName:string
    ) {}
}
  • JavaScript
class Player {
    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}
자바스크립트에서는 접근제한자가 사라짐.
하지만 TypeScript에서는 에러가 생기기전에 코드를 보호해줌
ex) nico.firstName //TypeScript에서는 Error가 발생하지만 자바스크립트에선 문제없음

 

class Player{
	constructor(
    	private firstName:string,
        private lastName:string,
        public nickname:string
    ) {}
}

const nico = new Player("nico", "las", "니꼬");

 

Abstract Class(추상클래스)

추상클래스: 다른 클래스가 상속받을 수 있는 클래스로 오직 다른 곳에서 상속받을 수만 있고 직접 인스턴스를 생성하지 못함!

abstract class User{
	constructor(
    	private firstName:string,
        private lastName:string,
        public nickname:string
    ) {}
    getFullName(){
    	return '${this.firstNme} ${this.lastName}'
    }
}

class Player extends User {

}

 

Abstract Method(추상함수)

메소드를 추상클래스 안에서 구현하지 않고 메소드의 call signature만 적어둬야 함

abstract class User{
	constructor(
		protected firstName:string,
		protected lastName:string,
		protected nickname:string
	) {}
	abstract getNickName():void
	getFullName(){
		return '${this.firstNme} ${this.lastName}'
	}
}

class Player extends User {
	getNickName(){
		console.log(this.nickname);
	}
}

 

Access Modifiers(접근 제한자)

  • public : 클라스의 외부에서 접근 가능
  • private : 클라스 내에서만 접근 가능, 클라스의 외부에서 접근 불가능
  • protected : 클라스 내부, 그리고 상속받은 자식 클라스에서 접근 가능

 

type Words = {
	[key:string]: string
}

let dict: Words = {
	"potato" : "food"
	1 : "food	//Error!
}

-> Words는 타입이 string만을 property로 가지는 오브젝트임

 

type Words = {
    [key:string]: string
}

class Dict {
    private words: Words
    constructor(){
    	this.words = {}
    }
    
    add(word:Word){
    	if(this.words[word.term] === undefined){
        	this.words[word.term] = word.def;
        }
    }
    
    def(term:string){
    	return this.words[term]
    }
}

class Word {
    constructor(
    	public term:string,
        public def: string
    ){}
}

const kimchi = new Word("kimchi", "한국의 음식");

const dict = new Dict();
dict.add(kimchi);
dict.def("kimchi");

 

readonly (읽기전용)

public 이지만 더 이상 변경할 수 없도록 만들 때 사용

주로 다른 누군가가 데이터를 덮어쓰는걸 방지하기 위해서

class Word{
	constructor(
    	public readonly term: string,
        public readonly def: string
    ){}
}

const kimchi = new Word("kimchi", "한국의 음식");
kimchi.def = "xxx" //Error!

 

Interface

  • type : 오브젝트의 모양을 묘사하는데 쓸 수도 있고 타입 alias를 만들 수 있음
type Team = "red" | "blue" | "yellow"
type Health = 1 | 5 | 10

type Player = {
	nickname : string,
	team : Team,
	health : Health
}

const nico : Player = {
	nickname : "nico",
    team : "pink", //Error!
    health : 5
}
  • interface : 오브젝트의 모양을 특정해주기 위해 사용
interface Player {
	nickname : string,
	team : Team,
	health : Health
}

What is the difference between a type and an interface?

> Interfaces can only be used to type an object, a Type can be used for any type.

(인터페이스는 오로지 오브젝트의 모양을 타입스크립트에게 설명해주기 위해서만 사용되는 키워드임)

 

abstract class User{
    constructor(
        private firstName:string,
        private lastName:string,
    ) {}
    abstract sayHi(name:string):string
    abstract fullName():string
}

class Player extends User {
    fullName(){
    	return '${this.firstName} ${this.lastName}'
    }
    sayHi(name:string){
    	return 'Hello ${name}. My name is ${this.fullName()}'
    }
}

What is the difference between an abstract class and a "normal" class?

> We can't make an instance of an abstract class. but Abstract class will become a normal class in JS.

추상 클래스는 인스턴스 만드는 것을 허용하지 않음.  new User() //Error!

추상 클래스는 단지 상속받는 클래스가 어떻게 동작해야할지 알려주기 위해(표준화하기위해)서 사용됨

하지만 자바스크립트에서는 abstract의 개념이 없기 때문에 일반적인 클래스로 바꿔버림.

  • javascript (abstract -> class)
class User {
    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}
class Player extends User {
    fullName() {
        return '${this.firstName} ${this.lastName}';
    }
    sayHi(name) {
        return 'Hello ${name}. My name is ${this.fullName()}';
    }
}

 

인터페이스는 컴파일하면 자바스크립트에서 바뀌지않고 사라짐

interface User{
    firstName:string,
    lastName:string
    sayHi(name:string):string
    fullName():string
}

class Player implements User{
    constructor(
        public firstName:string,
        public lastName:string,
    ) {}
    fullName(){
    	return '${this.firstName} ${this.lastName}'
    }
    sayHi(name:string){
    	return 'Hello ${name}. My name is ${this.fullName()}'
    }
}
class Player {
    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    fullName() {
        return '${this.firstName} ${this.lastName}';
    }
    sayHi(name) {
        return 'Hello ${name}. My name is ${this.fullName()}';
    }
}

하지만 인터페이스를 상속하면 private property들을 사용하지 못하고 매번 constructor를 선언해줘야한다는 문제점이 있지만

인터페이스를 만들어두고 원하는 각자의 방식으로 클래스를 상속할 수 있다는 장점도 있음

 

Polymorphism(다형성)

제네릭을 사용하여 다형성(다른 모양의 코드를 가질 수 있게 해줌)을 이룰 수 있음

제네릭을 클래스로 보내면 클래스는 제네릭을 인터페이스로 보내줄 수 있음

 

  • 일반적인 자바스크립트에서 사용한 로컬 스토리지 API와 같은 API를 가지는 클래스 만들기
interface SStorage<T> {
	[key:string]: T
}

class LocalStorage<T> {
    private storage: SStorage<T> = {}
    set(key:string, value:T){
    	this.storage[key] = value;
    }
    remove(key:string){
    	delete this.storage[key]
    }
    get(key:string):T {
    	return this.storage[key]
    }
    clear(){
    	this.storage = {}
    }
}

const stringsStorage = new LocalStorage<string>();
stringsStorage.get("key");	//get(key: string): string
stringsStorage.set("hello", "how are you"); //set(key:string, value:string): void

const booleansStorage = new LocalStorage<boolean>();
booleansStorage.get("key");	//get(key: string): boolean
stringsStorage.set("hello", true);
728x90
Share Link
reply
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31