TypeScript -8-

mh·2022년 5월 4일
0

TypeScript

목록 보기
8/17
post-thumbnail

Photo by Cristian Palmer on Unsplash

TypeScript OOP

  • 타입스크립트로 클래스를 만드는 방법
  • 타입스크립트가 중복된 코드를 막는 방법

TS에서 class 만들기

"use strict";
class Player {
    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

자바스크립트와 달리 파라미터들을 써주기만 하면 TS가 알아서 Constructor 함수를 만들어줌

class Player {
	constructor {
    	private firstName: string,
        private lastName: string
    } {}
}

public property 추가하고 새로운 플레이어 생성하기

class Player {
	constructor {
    	private firstName: string,
        private lastName: string,
        public nickName: string
    } {}
}

const ulfric = new Player("Ulfric"," Stormcloak","The rebel")

private 변수에 접근하려하면 TS가 막아줌

TS의 추상클래스(abstract class)

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

  • abstract class User {}로 추상클래스를 만든 후
  • Plyaer class에 있던 constructor들을 넣어주기
  • class Plyaer extend User로 Plyaer가 User를 상속한다고 알려주기
abstract class User {
        constructor (
        private firstName:string,
        private lastName:string,
        public nickName:string
    ) {}
}

class Player extends User {

}

const ulfric = new Player("Ulfric"," Stormcloak","The rebel");

추상 클래스는 자기가 직접 새로운 인스턴스를 만들 수는 없음

ex)

const ulfric = new User("Ulfric"," Stormcloak","The rebel"); //error

추상클래스는 오직 다른곳에서 상속받을수만 있는 클래스

추상메소드 (abstract method)

추상클래스 안의 일반 메소드

추상클래스 User 안에 getFullName이라는 메소드를 추가

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

class Player extends User {

}

const ulfric = new Player("Ulfric"," Stormcloak","The rebel");

ulfric.getFullName();

User로 부터 상속받았으므로 Plyaer가 getFullName 메소드를 사용가능

Private Method

추상메소드도 private으로 지정할 수 있음

private getFullName() {
        return `${this.firstName} ${this.lastName}`
}

private, public은 property 뿐만 아니라 method에서도 작동함

자바스크립트 코드와 비교

  • JavaScript

     "use strict";
     class User {
         constructor(firstName, lastName, nickName) {
             this.firstName = firstName;
             this.lastName = lastName;
             this.nickName = nickName;
         }
         getFullName() {
             return `${this.firstName} ${this.lastName}`;
         }
     }
     class Player extends User {
     }
     const ulfric = new Player("Ulfric", " Stormcloak", "The rebel");
  • TypeScript

     abstract class User {
             constructor (
             private firstName:string,
             private lastName:string,
             public nickName:string
         ) {}
         private getFullName() {
             return `${this.firstName} ${this.lastName}`
         }
     }
    
     class Player extends User {
    
     }
    
     const ulfric = new Player("Ulfric"," Stormcloak","The rebel");

추상 클래스 안의 추상메소드 만들기

      private getFullName() {
          return `${this.firstName} ${this.lastName}`
      }

이런식으로 메소드를 직접 구현하지 말고

메소드의 콜 시그니처만 적어둬야 함

User 추상클래스 안에 getNickName라는 추상메소드 만들기

abstract class User {
        constructor (
        private firstName:string,
        private lastName:string,
        private nickName:string
    ) {}
    abstract getNickName():void
    private getFullName() {
        return `${this.firstName} ${this.lastName}`
    }
}

class Player extends User {

}

const ulfric = new Player("Ulfric"," Stormcloak","The rebel");

arguments를 추가할 수 있음

Player가 getNickName 추상메소드를 구현하지 않았다고 나옴

추상메소드는 추상 클래스를 상속받는 모든 것들을 구현해야 하는 메소드

Plyaer에서 getNickName 구현하기

player에서 nickname에 접근하려하면 에러가 뜸
상속받은 클래스일지라도 priavte property에는 접근 불가임

이건 필드를 보호하기 위한 방법이 private과 public 뿐만 아니라 protected라는 방법이 있기 때문

만약 추상 클래스안에 private 필드가 있다면 private 프로퍼티들은 인스턴스 밖에서 접근할 수 없고, 다른 서브 클래스에서도 접근할 수 없음

원래는 User 클래스의 인스턴스나 메소드에서 접근 할 수 있으나,
User는 추상클래스이기 때문에 인스턴스화 할 수 없고 때문에 User를 상속받아도 private 필드는 사용할 방법이 없음

만약 추상클래스안의 private필드를 외부에서 접근은 막고, 인스턴스나 서브클래스에서 사용하고 싶다면 protected 필드를 사용해야함.


이제 Player에서 getNickName을 구현하기 위해 this.를 입력하면 나머지 프로퍼티들에 접근할 수 있음

클래스밖에서는 User 프로퍼티에 접근할 수 없도록 보호해줌

클래스 밖에서 nickname에 직접 접근할 순 없지만 User로부터 상속받은 getNickName()을 이용해 nickname에 접근가능

정리

  • TS클래스에서는 JS에서는 보이지 않는 protect레벨을 설정할 수 있음(접근제어자)
  • public, private, protected 3가지 필드가 있음
  • protectField properyName: type,
  • 클래스를 상속할 수 있고 추상클래스를 만들 수 있음
  • 추상클래스는 자신이 인스턴스를 만들 수 없지만 다른 클래스에 상속은 가능함
  • 메소드 또한 public, private, protected로 접근레벨을 설정 할 수 있음

  • 추상 메소드는 구현이 되어있지 않은(코드가없는) 메소드
  • 추상 메소드는 콜 시그니처만 가지고 있음
  • 추상 메소드는 함수이름과 인수를 받을 수 있음
  • 받을 경우 인수의 이름과 타입 그리고 함수의 리턴타입을 정의해야함
abstract getLastName():void
abstract getArg(arg:number):number
  • 상위 클래스에서 추상메소드를 상속받은 하위 클래스는 상위 클래스의 추상메소드를 자신이 구현해주어야 함
class Player extends User {
	getLastName() {
    	console.log(this.lastName);
    }
  	getArg(arg:number):number {
      	console.log(arg);
    	return arg;
    }
}
  • 상위 클래스의 constructor 내부 property들이나 메소드들을 private으로 바꾼다면 하위 클래스는 상위클래스의 프로퍼티와 메소드를 상속받지 못함
  • private일 경우 오직 해당 class 안에서만 접근가능
  • 메소드를 이용해서 private 키워들 사용하면 외부에서도 접근가능
  • 메소드도 공개하기 싫다면 메소드에 private이나 protected키워드 사용
  • 상속가능한 프로퍼티나 메소드를 만들고 싶다면 protected 키워드를 사용해 만들어야 함
  • 외부의 모든곳에서 사용가능한 프로퍼티 혹은 메소드를 만들고 싶다면 public으로 지정하거나 키워드없이 선언하면 됨 (*컨스트럭터 프로퍼티는 꼭 키워드를 붙여줘야함)
abstract class 유저 {
	constructor (
  		private 오직User안에서만접근가능:string,
        protected 상속하면접근가능:string,
        public 모든곳에서접근가능:string,
        //이것도모든곳에서접근가능:string <- 이건 안됨
  	) {}
  	
  	// 이렇게는 public없이도 됨
  	프라이빗접근하기() {
        console.log(this.오직User안에서만접근가능)
        return this.오직User안에서만접근가능;
    }
}

class 플레이어 extends 유저 {
	
}

const 새플레이어 = new 플레이어 ("오직유저안에서만","상속하면접근가능","모든곳에서접근가능")

// 새플레이어.오직User안에서만접근가능 // error
새플레이어.프라이빗접근하기()
console.log(새플레이어.모든곳에서접근가능,"추상클래스안의프라이빗프로퍼티")



ts playground 참고

abstract class User {
        constructor (
        protected firstName:string,
        protected lastName:string,
        protected nickName:string,
        private 오직유저안에서만접근가능?:string,
        public 모든곳에서접근가능?:string
    ) {}
    abstract getArg(arg:number):number
    abstract getNickName():void

    접근할래() {
        console.log(this.오직유저안에서만접근가능,"<-뭐라고나옴?")
        return this.오직유저안에서만접근가능
    }

    public getLastName() {
        return `$(this.lastName} `
    }
    private getFullName() {
        return `${this.firstName} ${this.lastName}`
    }
}

class Player extends User {
    
    nickname!: string;
    
    getNickName() {
        console.log(this.nickName);
        console.log(this.firstName);
    }
    getArg(arg:number) {
        console.log(arg)
        return arg
    }
}

const ulfric = new Player("Ulfric"," Stormcloak","The rebel","프라이빗이얌","모든곳에공개");
ulfric.nickname
// ulfric.getFullName()
ulfric.getLastName()
ulfric.getNickName()
ulfric.getArg(1)
// ulfric.오직유저안에서만접근가능
ulfric.접근할래()
ulfric.모든곳에서접근가능

실행값

profile
🤪🤪🤪🤪🤪

0개의 댓글