객체지향 프로그래밍

ZeroJun·2022년 7월 1일
1

타입스크립트

목록 보기
3/4

해시맵 만들기

// 해시맵 만들기
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;
    }
  }
  get(term: string) {
    return this.words[term];
  }
  delete(term: string) {
    if (!this.words[term]) return false;
    delete this.words[term];
    return true;
  }
  update(term: string, def: string) {
    if (!this.words[term]) return false;
    this.words[term] = def;
    return this.words[term];
  }
  showAll() {
    return this.words;
  }
  count() {
    return Object.keys(this.words).length;
  }
}

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

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

const dict = new Dict()

dict.add(kimchi)
console.log(dict.get("kimchi"))

// dict.delete("kimchi")
// console.log(dict.get("kimchi"))

// dict.update("kimchi", "수정")
// console.log(dict.get("kimchi"))

// console.log(dict.get("kimchi"))

// const apple = new Word("apple", "과일")
// dict.add(apple)
// console.log(dict.showAll())

// const apple = new Word("apple", "과일")
// dict.add(apple)
// const banana = new Word("banana", "과일")
// dict.add(banana)
// console.log(dict.count())

인터페이스

type과 인터페이스의 차이와 인터페이스의 기본

// Type과 interface
type Team = "read" | "blue" | "yellow";
type Health = 1 | 5 | 10; // 인터페이스는 이런건 불가능하다.

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

interface Player { // 위 아래 둘다 똑같이 작동한다.
  nickname: string;
  team: Team;
  health: Health;
}
// 인터페이스는 오로지 오브젝트의 모양을 
// 타입스크립트에게 설명해주기 위해서만 사용되는 키워드다.

const nico: Player = {
  nickname: "nico",
  team: "yellow",
  health: 10,
};



// interface로 상속구현
interface User1 {
  name: string
}
interface Player1 extends User1 {

}

const jyj : Player1 = {
  name:"jyj"
}

// 타입으로 상속구현
type User2 = {
  name: string
}
type Player2 = User2 & {

}

const jyj2 : Player2 = {
  name:"jyj"
}

클래스나 오브젝트의 모양을 정의할 때는 인터페이스를 사용하고 나머지는 type을 사용한다.(type alias나 특정 값으로 타입을 제한하는 경우 등)

추상클래스와 인터페이스

// 추상클래스는 표준화된 property와 메소드를 갖도록 해주는
// 청사진을 만들기 위해 사용한다.
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}`;
  }
}


// 위와 같은 추상클래스는 인터페이스로 바꿀 수 있다.
interface User {
  firstName: string;
  lastName: string;
  sayHi(name: string): string;
  fullName(): string;
}

interface Human {
  health: number;
}

class Player implements User, Human {
  // 다중 상속 가능
  // interface를 상속받으면 private이나 protect를 사용할 수 없다.
  constructor(
    public firstName: string,
    public lastName: string,
    public health: number
  ) {}
  fullName() {
    return `${this.firstName} ${this.lastName}`;
  }
  sayHi(name: string) {
    return `Hello ${name}. My name is ${this.fullName}`;
  }
}

// 인터페이스를 타입으로 받기, 리턴하기

// User인터페이스를 타입으로 받고 User인터페이스를 리턴
function makeUser(user: User) : User { 
  return {
    firstName: "hi",
    lastName: "bye",
    sayHi: (name) => "hi",
    fullName: () => "wow",
  }; // 클래스를 리턴할 때 처럼 new User()같은 것을 할 필요가 없다.
}

makeUser({
  firstName: "hi",
  lastName: "bye",
  sayHi: (name) => "hi",
  fullName: () => "wow",
});

다형성 (polymorphism)

// LocalStorage API
interface SStorage<T> {
  [key: string]: T;
}

abstract class StorageTemplate<T> {
  protected storage: SStorage<T> = {};
  abstract setItem(key: string, value: T): void;
  abstract getItem(key: string): T | boolean;
  abstract clearItem(key: string): void;
  abstract clear(): void;
}

class LocalStorage<T> extends StorageTemplate<T> {
  setItem(key: string, value: T) {
    this.storage[key] = value;
  }
  getItem(key: string): T | boolean {
    return this.storage[key] || false;
  }
  clearItem(key: string) {
    delete this.storage[key];
  }
  clear() {
    this.storage = {};
  }
}

// polymorphism 
const stringStorage = new LocalStorage<string>(); 
stringStorage.setItem("안녕", "반가워");
stringStorage.getItem("안녕");
const booleanStorage = new LocalStorage<boolean>();
booleanStorage.setItem("안녕", true);
booleanStorage.getItem("안녕");

오버로딩

interface IGeolocation {
  clearWatch(watchId: number): void;
  getCurrentPosition(
    successCallback: IPositionCallback,
    errorCallback?: IPositionErrorCallback | null,
    options?: IGeolocationOptions
  ): void;
  watchPosition(
    successCallback: PositionCallback,
    errorCallback?: IPositionErrorCallback | null,
    options?: IGeolocationOptions
  ): number;
}

// successCallback interface
interface IPositionCallback {
  (position: IGeolocationPosition): void;
}
interface IGeolocationPosition {
  readonly coords: IGeolocationCoordinates;
  readonly timestamp: IEpochTimeStamp;
}
interface IGeolocationCoordinates {
  readonly accuracy: number;
  readonly altitude: number | null;
  readonly altitudeAccuracy: number | null;
  readonly heading: number | null;
  readonly latitude: number;
  readonly longitude: number;
  readonly speed: number | null;
}
type IEpochTimeStamp = number;

// errorCallback interface
interface IPositionErrorCallback {
  (positionError: IGeolocationPositionError): void;
}
interface IGeolocationPositionError {
  readonly code: number;
  readonly message: string;
  readonly PERMISSION_DENIED: number;
  readonly POSITION_UNAVAILABLE: number;
  readonly TIMEOUT: number;
}

// option interface
interface IGeolocationOptions {
  enableHighAccuracy: boolean;
  timeout: number;
  maximumAge: number;
}

// Geolocation class
class GGeolocation implements IGeolocation {
  clearWatch(watchId: number) {
    console.log(watchId);
  }
  getCurrentPosition(
    successCallback: IPositionCallback,
    errorCallback?: PositionErrorCallback | null,
    options?: PositionOptions
  ) {
    if (successCallback) console.log(successCallback);
    if (errorCallback) console.log(errorCallback);
    if (options) console.log(options);
  }
  watchPosition(
    successCallback: PositionCallback,
    errorCallback?: PositionErrorCallback | null,
    options?: PositionOptions
  ) {
    if (successCallback) console.log(successCallback);
    if (errorCallback) console.log(errorCallback);
    if (options) console.log(options);
    return 0;
  }
}

const geolocation = new GGeolocation();
// 오버로딩
geolocation.getCurrentPosition(test);
geolocation.getCurrentPosition(test, test);
geolocation.getCurrentPosition(test, test, {});

function test() {}

0개의 댓글