목차
- 클래스(추상 클래스, 추상메서드)
- interfaces와 type
- interface와 type의 비교
- 인터페이스 사용해서 클래스가 특정 모양을 따르도록 하기
1. 클래스
class Player {
constructor(
private firstName: string,
private lastName: string,
public nickname: string
){}
}
const son = new Player('heungmin','son','쏘니');
son.firstName // 에러 발생.속성값 firstName은 private하며 'Player' 클래스 내부에서만 접근 가능함
1-1. 추상클래스란?
- 다른 클래스가 상속받을 수 있는 클래스
- 직접 새로운 인스턴스를 생성할 수는 없는 클래스
- 자바스크립트로 컴파일됨( JS에서는 일반 클래스로 변경됨. 즉, 파일크기가 좀 더 커지고 추가 클래스가 생성됨)
1-2. 추상클래스를 사용하는 이유?
- 다른 클래스들이 표준화된 모양과 속성 그리고 표준화된 메서드를 갖도록 해주는 청사진을 만들기 위해 사용
- 추상클래스를 다른 클래스들이 특정 모양을 따르도록 하기 위한 용도로 쓴다면 추상 클래스보다는 인스턴스 사용을 추천
- (인터페이스의 경우 타입스크립트에 의해 보호는 되지만, 자바스크립으로 컴파일 되지 않음)
abstract class User { // 다른 클래스에게 상속할 수 있지만 직접 새로운 인스턴스 생성은 불가한 클래스
constructor(
private firstName: string, // 접근제어자, 속성명: 데이터 유형
private lastName: string,
public nickname: string
){}
getFullName(){ // 추상 클래스 안에 있는 메소드
return `${this.firstName} ${this.lastName}` // 메소드의 구현(implementation)
}
}
class Player extends User{
}
const son = new Player('heungmin','son','쏘니');
sont.getfullName()
1-3. 추상 메소드
- 추상 클래스 안에서 생성되지만
- 메서드가 구현되어서는 안되며,( =코드가 없는)
- 코드블럭 내부에는 메소드의 call signature만 작성되어야 함
- 추상 클래스를 상속받는 모든 것들이 구현 해야 하는 메소드
추상 메소드가 있는 경우, 추상 클래스를 상속받는 클래스에서는 반드시 추상 메소드를 구현해야 함
(즉, 추상 클래스 내부에 콜 시그니쳐 작성, 상속받는 클래스에서 코드 작성)
1-4. 필드 접근 제어자(필드의 보호 등급)
- private: 인스턴스 외부 및 자식 클래스에서 접근 불가
- protected: 인스턴스 외부에서는 접근 불가하나 자식 클래스에서는 접근 가능
- public: 인스턴스 외부 및 자식 클래스에서 접근 가능(디폴트)
1-5. 객체의 키값에 데이터 유형 지정
type Words1 = {
[key: number]: string // Words 타입이 number 만을 속성으로 가지는 객체
}
let dict1 : Words1 = {
1: "food",
2: "",
3: ""
}
type Words2 = {
[key: string]: string // Words 타입이 string 만을 속성으로 가지는 객체
}
let dict2 : Words2 = {
"potato": "food",
"carrot": "food",
}
1-6. 해시맵 생성
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;
}
}
delete(word: Word){
if(this.words[ word.term ] ){
delete this.words[ word.term ] = undefined;
}
}
update(word: Word) {
if ( this.words [word.term ] ){
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 Dick()
dict.add(kimchi);
1-7. static 메소드
class Dict {
private words: Words
constructor() {
}
static hello() {
return 'hello'
}
}
객체의 모양을 특정하는 두 가지 방법
- 타입
- 인터페이스
2. type과 interface
2-1. type 이란?
(1) 타입 스크립트에게 객체의 모양을 설명해줄 수 있음
type Player = {
nickname: string,
healthBar: number
}
const son: Player = {
nickname: 'sonny',
healthBar: 10
}
2. 클래스의 데이터 유형을 선언
type Food = string;
const kimchi: Food = 'delecious'
type Friends = Array<string> // type Friends가 string의 배열이라는 것을 선언
3. 타입을 concrete 유형의 특정 값으로 제한
type Team = 'red' | 'blue' | 'yellow'
type Player = {
nickname: string,
team: Team;
}
const son: Player = {
nickname: 'son',
team: 'red' // 'red' 또는 'blue' 또는 'yellow' 중 한가지의 값만 사용 가능
}
2-2. 인터페이스란?
- 오직 객체(object)의 모양을 특정
- 자바스크립트로 컴파일 되지 않음
- 즉, 추상 클래스와 비슷한 보호를 제공하지만 자바스크립트 파일에서 보이지 않음
type Team = 'red' | 'blue' | 'yellow'
interface Player{ // 작성된 인터페이스와
nickname: string,
team: Team
}
type Player = { //작성된 타입의 역할은 완전 같다.
nickname: string,
team: Team
}
3. 타입과 인터페이스의 차이점
3-1. 인터페이스/타입의 상속
(1) 인터페이스의 상속
interface User {
name:string
}
interface Player extends User { // 문법 구조가 객체지향 프로그램과 비슷하다
}
const son: Player = {
name: 'son'
}
(2) 타입의 상속
type User = {
name: string
}
type Player = User & { // & 연산자 사용
}
const son: Player = {
name: 'son'
}
3-2. 인터페이스의 속성 축적
interface User {
name: string
}
interface User {
lastName: string
}
interface User {
health: number
}
const son: User = {
name: 'son',
lasName: 'heungmin',
number: 7
}
3-3. 타입과 인터페이스 비교
타입(type) | 인터페이스(interface) |
용도가 매우 다양 | 클래스나 객체의 모양을 특정할 때 사용 |
클래스의 데이터 유형 선언 | 문법이 객체 지향 프로그램과 비슷 |
타입 alias 생성 가능 | 속성의 축적 가능 (extendable) |
타입을 concrete 유형의 특정 값으로 제한 가능 |
4. 인터페이스 사용 시, 클래스가 특정 형태를 따르도록 강제하기
추상클래스를 인터페이스로 바꿔보자
interface User{
firstName: string,
lastName: string,
sayHi(name:string): string,
fullname(): string
}
interface Human {
health: number
}
class Player implements User, Human{ //Player가 User와 Human 두개의 인터페이스를 상속받음
constructor(
private firstName: string, // 인터페이스 상속 시는 속성에 private 적용 불가
private lastName: string
){}
fullName(){
return `${this.firstName} ${this.lastName}`
}
sayHi(name:string){
return `Hello ${name}. My name is ${this.fullName()}`
}
}
// 아래와 같은 방식으로 인터페이스도 타입으로 사용 가능하다
function makeUser(user: Player){ // 함수의 인자값에 인터페이스 작성해서 객체의 모양 지정
return 'hi'
}
makeUser({
firstName: 'son',
lastName: 'heungmin',
fullName() => 'son'
sayHi(name) => 'string'
})
로컬 API와 동일한 형태를 따르되 제네릭 사용
interface SStorage<T> {
[key:string] : T
}
class LocalStorage<T>{
private storage: SStorage<T> = {}
set(key:string,value:T){
this.storage[key] = value;
//API 디자인의 구현
}
remove(key:string){
delete this.storage[key]
}
get(key:string):T {
return this.stoarge[key]
}
clear(){
this.storage = {}
}
}
const stringsStorage = new LocalStorage<string>() // TS가 제네릭을 바탕으로 콜 시그니쳐 생성해줌
stringsStorage.get('key') // string
stringsStorage.set('hello','how are you?')
const booleansStorage = new LocalStorage<boolean>()
booleansStorage.get('key') // boolean
booleansStorage.set('hello',true)
'타입스크립트' 카테고리의 다른 글
타입스크립트5. 함수의 call signatures (0) | 2022.05.15 |
---|---|
타입스크립트4. 데이터 타입(2) (0) | 2022.05.15 |
타입스크립트3. 데이터 타입(1) (0) | 2022.05.15 |
댓글