#4 Classes and Interfaces

#4.0 Classes

TS๋กœ ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํ•˜๊ธฐ

class Player {
    constructor (
        private firstName: string, // JS ์—๋Š” private๊ฐ€ ์—†์Œ TS์—์„œ๋งŒ ์ž‘๋™
        private lastName: string,
        public nickname: string
    ) {}
}

const nic = new Player("nic", "las", "n")

nic.firstname // TS์—์„œ์ž‘๋™ ์•ˆํ•จ private ์ด๊ธฐ์—
nic.nicname // ์ž‘๋™

Abstract - ๋‹ค๋ฅธ ํด๋ž˜์Šค๊ฐ€ ์ƒ์†๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ํด๋ž˜์Šค, ์ง์ ‘ ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜๋Š” ์—†์Œ JS์—๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์Œ Only TS

abstract class User {    // ์ถ”์ƒ ํด๋ž˜์Šค
    constructor (
        private firstName: string,
        private lastName: string,
        public nickname: string
    ) {}
    abstract getNickName(): void // absc- ์•ˆ์— absc ๊ฐ€๋Šฅ, class์—์„œ ๋ฐ˜๋“œ์‹œ ๊ตฌํ˜„ํ•ด์•ผํ•จ
    
    getFullName(){    // ์ถ”์ƒ ๋ฉ”์†Œ๋“œ
        return `${this.firstName} ${this.lastName}`
    }
}

class Player extends User {
    ...
}

const nic = new Player("nic", "las", "n")
nic.getFullName() // "nic las"

์ ‘๊ทผ ๊ฐ€๋Šฅ ์œ„์น˜

๊ตฌ๋ถ„
์„ ์–ธํ•œ ํด๋ž˜์Šค ๋‚ด
์ƒ์†๋ฐ›์€ ํด๋ž˜์Šค ๋‚ด
์ธ์Šคํ„ด์Šค

private

O

X

X

protected

O

O

X

public

O

O

O

=> TS์—์„œ ์ฒดํฌํ•˜๊ณ  JS์—์„œ๋Š” ๋ณด์ด์ง€ ์•Š์Œ

#4.1 Recap

4.0 ๋ณต์Šต

type Words = {
    [key: string] : string // Words ํƒ€์ž…์ด string๋งŒ์„ ํ”„๋กœํผํ‹ฐ๋กœ ๊ฐ–๋Š” ์˜ค๋ธŒ์ ํŠธ
}

class Dic {
    private words: Words
    constructor() {
        this.words = {}
    }
    add(word: Word){ // ํด๋ž˜์Šค๋ฅผ ํƒ€์ž…์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค
        if(this.words[word.term] === undefined){
            this.words[word.term] = word.def;
        }
    }
    def(tern: string){
        return this.words[term]
    }
}

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

const kimchi = new Word("kimchi", "ํ•œ๊ตญ์Œ์‹")

const dic = new Dic(kimchi)
dic.add(kimchi)
dic.def("kimchi")

+ mission

#4.2 Interfaces

ํƒ€์ž…๊ณผ ๋น„์Šทํ•˜์ง€๋งŒ ๋‹ค๋ฆ„

// ํƒ€์ž…
// ํŠน์ • ๊ฐ’๋งŒ ๊ฐ€์ง€๋„๋ก ์ œํ•œ ๊ฐ€๋Šฅ
type Team = "MU" | "BM" | "NA"
type Health = 1 | 5 | 10
type Player = {
    nickname: string,
    team: Team,
    health: Health,
}

const kim : Player = {
    nickname: Kim,
    team: BM,
    health: 11 // err : ์„ค์ •๋œ ํƒ€์ž…์ด ์•„๋‹ˆ๊ธฐ์— ์—๋Ÿฌ ๋ฐœ์ƒ
}

Interface - ์˜ค์ง ํ•œ๊ฐ€์ง€ ์šฉ๋„๋กœ ์˜ค๋ธŒ์ ํŠธ์˜ ๋ชจ์–‘์„ ํŠน์ •ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ

// ์ธํ„ฐํŽ˜์ด์Šค
type Team = "MU" | "BM" | "NA"
type Health = 1 | 5 | 10

interface Player {
    nickname: string,
    team: Team,
    health: Health,
}

const kim : Player = {
    nickname: Kim,
    team: BM,
    health: 11 // err : ์„ค์ •๋œ ํƒ€์ž…์ด ์•„๋‹ˆ๊ธฐ์— ์—๋Ÿฌ ๋ฐœ์ƒ
}

type๊ณผ interface๋Š” ์˜ค๋ธŒ์ ํŠธ์˜ ๋ชจ์–‘์„ ํŠน์ •ํ•˜๊ธฐ ์œ„ํ•œ ์šฉ๋„์ด๋ฏ€๋กœ ๊ฑฐ์˜ ๊ฐ™์Œ

interface User {
    name: string
}

interface Player extends User {}

const kim : Player = {
    name: "Kim"
}

/////////

type User = {
    name: string
}

type Player = User & {}

const kim : Player = {
    name: "Kim"
}

interface๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ๊ฐœ๋…์„ ํ™œ์šฉํ•ด ๋””์ž์ธ๋˜์—ˆ๊ณ , ํƒ€์ž…์€ ๋” ์œ ์—ฐํ•˜๊ณ  ๊ฐœ๋ฐฉ์ ์ž„

// Interface ํ”„๋กœํผํ‹ฐ์˜ ์ถ•์ ์ด ๊ฐ€๋Šฅํ•จ
interface User {name: string}
interface User {lastName: string}
interface User {age: number}

const nico :User = {
    name: "nico",
    lastName: "n",
    age: 10
}

#4.3 Interfaces part Two

์ธํ„ฐํŽ˜์ด์Šค๋Š” ๊ฐ€๋ณ๋‹ค. ์ปดํŒŒ์ผํ•˜๋ฉด JS๋กœ ๋ณ€ํ•˜์ง€ ์•Š๊ณ  ์‚ฌ๋ผ์ง€๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

abstract class User {
    constructor(
        protected firstName: string,
        protected 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()}`
    }
}


// => abstract ๋ฅผ interface ๋กœ ๋ณ€๊ฒฝ
interface User {
    firstName: string,
    lastName: string, 
    sayHi (name: string):string
    fullName (): string
}

class Player implements User { // implements ๋Š” JS ์— ์‚ฌ์šฉ๋˜์ง€ ์•Š์Œ
    constructor(
        public firstName: string,
        public lastName: string
    ){}
    
    fullName(){
        return `${this.firstName} ${this.lastName}`
    }
    sayHi(name:string){
        return `Hello ${name}. My Name is ${this.fullName()}`
    }
}

์œ„ ๋‘ ์ฝ”๋“œ๋Š” ๊ฐ™์€ ๋‚ด์šฉ์„ abstract๋กœ ์ƒ์„ฑํ–ˆ์„ ๋•Œ์™€ interface๋กœ ์ƒ์„ฑํ–ˆ์„ ๋•Œ์˜ ์ฐจ์ด๋‹ค. ์ด๋ ‡๊ฒŒ ๋ณด๋ฉด ํฐ ์ฐจ์ด ์—†์–ด๋ณด์ด์ง€๋งŒ, JS๋กœ ์ปดํŒŒ์ผํ•œ ๋‚ด์šฉ์„ ์‚ดํŽด๋ณด๋ฉด ๋ถˆํ•„์š”ํ•œ User class๊ฐ€ ์‚ฌ๋ผ์ ธ์žˆ์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋งŒํผ ๋” ๊ฐ€๋ฒผ์›Œ์กŒ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.

#4.4 Recap

  1. Type๊ณผ Interface ๋Š” ์˜ค๋ธŒ์ ํŠธ์˜ ๋ชจ์–‘์„ ์ง€์ •ํ•˜๋Š” ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

type PlayerA = {
    name: string
}

const playerA: PlayerA = {
    name: "Kim MJ"
}

///

interface BlayerB {
    name: string
}

const playerB: PlayerB = {
    name: "Son HM"
}
  1. ์ถ”๊ฐ€์ ์ธ ๋ถ€๋ถ„์—์„œ ์ฐจ์ด๊ฐ€ ์ƒ๊ธด๋‹ค.

type PlayerA = {
    name: string
}

type PlayerAA = PlayerA & {
    lastName: string
}

const playerA: PlayerAA = {
    name: "MJ"
    lastName: "Kim"
}

///
interface PlayerB {
    name: string
}

interface PlayerBB extends PlayerB { // ์ด๋Ÿฐ ์‹์œผ๋กœ ์ƒ์† ๊ฐ€๋Šฅํ•˜๋‹ค.
    lastName: string
}

interface PlayerBB {    // ์ด๋Ÿฐ ์‹์œผ๋กœ ํ™•์žฅ ๊ฐ€๋Šฅํ•˜๋‹ค.
    health: 10
}

const playerB: PlayerB = {
    name: "HM"
    lastName: "Son"
    health: 10
}
  1. ์ถ”์ƒ class๋ฅผ ๋Œ€์ฒดํ•œ๋‹ค.

type PlayerA = {
    firstName: string
}

class User implements PlayerA {
    constructor(
        public firstName: string
    ){}
}

interface PlayerB {
    firstName: string
}

class User implements PlayerB {
    constructor(
        public firstName: string
    ){}
}

=> ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์— ์˜ค๋ธŒ์ ํŠธ์˜ ๋ชจ์–‘์„ ์•Œ๋ ค์ฃผ๊ณ  ์‹ถ์œผ๋ฉด interface, ๋‚˜๋จธ์ง€ ์ƒํ™ฉ์—์„œ๋Š” type์„ ์‚ฌ์šฉํ•ด๋ผ~

#4.5 Polymorphism

๋‹คํ˜•์„ฑ - ๋‹ค๋ฅธ ๋ชจ์–‘์˜ ์ฝ”๋“œ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š”๊ฒƒ. ์ œ๋„ค๋ฆญ(placeholder ํƒ€์ž…)์„ ์‚ฌ์šฉํ•œ๋‹ค.

interface SStorage<T> {
    [key: string]: T
}

class LocalStoage<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 stringsStroage = new LocalStorageMstring<string>()
stringsStorage.get("ee")
stringsStorage.set("hello", "world")
stringsStorage.set("hello", 1) // err T is string

const booleansStorage = new LocalStorage<boolean>()
booleansStorage.get("xxx")
stringsStorage.set("hello", "world")

Last updated

Was this helpful?