티스토리 뷰
클래스
클래스 선언
private과 public을 사용해서 클래스 프로퍼티를 선언할 수 있다. 두개 다 자바스크립트에서는 보이지않고 문제없이 작동하지만 private은 클래스 밖에서 수정할 수 없고 public은 가능하다. 생략해서 적으면 public이 된다.
class Player {
constructor(
private firstName:string,
private lastName:string,
public nickname:string
){}
}
const kim = new Player("code", "kim", 'code kim')
kim.lastName // 에러메세지를 띄움
kim.nickname // 문제 없음
추상 클래스
abstract 키워드로 만들 수 있다. 다른 클래스가 상속 받을 수 있는 클래스이다. 추상 클래스가 인스턴스를 직접 생성하는 것은 불가능하다.
abstract class User {
constructor(
private firstName:string,
private lastName:string,
public nickname:string
){}
}
class Player extends User {
}
const kim = new User("code", "kim", 'code kim') // 에러메세지를 띄움
const lee = new Player("code", "lee", 'code lee') // 문제 없음
추상 메소드
추상 메소드도 abstract 키워드로 만들 수 있다. abstract를 쓰고 콜시그니처를 작성해주면 된다. 코드는 구현하지 않아도 된다. 추상 메소드를 만들면 추상 클래스를 상속받는 클래스에서는 필수로 추상 메소드를 구현해야한다.
abstract class User {
constructor(
private firstName: string,
private lastName: string,
private nickname: string
) {}
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
abstract getNickname(): void; // 추상메소드
}
abstract class User {
constructor(
private firstName: string,
private lastName: string,
private nickname: string
) {}
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
abstract getNickname(): void;
}
class Player extends User { // getNickname 추상메소드를 구현하지 않아서 에러메세지를 띄움
}
private으로 프로퍼티를 선언했다면 상속받은 class에서도 private에는 접근할 수 없다.
abstract class User {
constructor(
private firstName: string,
private lastName: string,
private nickname: string
) {}
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
abstract getNickname(): void;
}
class Player extends User {
getNickname() {
console.log(this.nickname) // nickname에 접근할 수 없다고 에러메세지를 띄움
}
}
접근하기는 원하고 값은 변경하지 못하게 하려면 protected를 쓰면 된다.
abstract class User {
constructor(
protected firstName: string,
protected lastName: string,
protected nickname: string // protected
) {}
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
abstract getNickname(): void;
}
class Player extends User {
getNickname(): void {
console.log(this.nickname) // 이젠 접근할 수 있음
}
}
const lee = new Player('code', 'lee', 'code lee');
lee.nickname // 여전히 값을 수정하려고 하면 에러메세지를 띄움
클래스를 타입으로 쓸수도 있다.
type Words = {
[key: string]: string; // 객체의 타입을 설정할 때 사용, 타입만 알 때 사용함
};
class Word {
constructor(public term: string, public def: 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;
}
}
const kimchi = new Word('kimchi', 'Korean Food');
const dict = new Dict();
dict.add(kimchi);
dict.def('kimchi'); // "Korean Food"
값을 읽을수만 있게 하고 수정은 못하게 하고 싶으면 readonly를 사용하면된다. 주로 다른 누군가가 데이터를 덮어씌우는 것을 방지하기 위해 사용한다.
class Word {
constructor(
public readonly term: string,
public readonly def: string
) {}
}
const kimchi = new Word('kimchi', 'Korean Food');
kimchi.def = "Food" // readonly라서 에러메세지를 띄움
static을 사용하면 바닐라 자바스크립트 코드처럼 작동한다.
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;
}
static hello() { // static
console.log("hello")
}
}
인터페이스
객체의 타입을 정해주기 위한 방법은 두가지가 있다.
이렇게 타입을 정해서 넣어주는 방법과
type Nickname = string;
type Team = "red" | "blue" | "yellow" // 이렇게 값을 제한적으로 들어가게도 할수있음
type Player = {
nickname:Nickname,
team: Team
}
const bong : Player = {
nickname : "bong",
team : "red" // type Team에 있는 값을 넣었기 때문에 에러메세지를 띄우지 않음
}
const kim : Player = {
nickname : "kim",
team : "white" // type Team에 있는 값을 넣지 않았기 때문에 에러메세지를 띄움
}
인터페이스를 사용하는 방법이 있다. React에서 많이 사용하고 타입스크립트에만 있기 때문에 자바스크립트 코드로 바꾸면 보이지 않는다.
type Nickname = string;
type Team = "red" | "blue" | "yellow"
interface Player {
nickname:Nickname,
team: Team
}
const bong : Player = {
nickname : "bong",
team : "red"
}
인터페이스 키워드를 사용하면 타입 키워드처럼 다양하게 사용할 수 없다. 인터페이스는 오직 객체의 모양을 정해주기 위해서만 존재한다.
type Name = string; // 사용 가능
interface Score = number; // 사용 불가능, 에러메세지를 띄움, =을 사용하지 않음
사용할 때는 형식이 똑같고 둘 중에 무엇을 사용해도 상관은 없다.
// type keyword
type User = {
name: string
}
type Player = User & { // type이 상속을 이용하는 방법 &
}
const bong : Player = { // 똑같음
name :"bong"
}
// interface keyword
interface User {
name: string
}
interface Player extends User {
}
const bong : Player = { // 똑같음
name :"bong"
}
인터페이스는 같은 이름으로 여러번 선언해도 타입스크립트에서 알아서 합쳐준다.
interface User {
name: string
}
interface User {
age: 10
}
const bong : User = {
name :"bong",
age : 20
}
// type keyword는 사용 불가
type User = { // 중복이라서 에러메세지를 띄움
name: string
}
type User = { // 중복이라서 에러메세지를 띄움
age: 10
}
인터페이스를 사용해야 할 때
추상 클래스를 사용했을 때 자바스크립트 코드로 컴파일하면 추상 클래스와 상속받은 클래스 모두가 나타난다. 추상 클래스를 사용하지 않는데도 불필요하게 추상 클래스가 존재한다. 그럴 때 타입을 사용할 수도 있지만 인터페이스를 사용하면 상속이 편리하다는 이점이 있다.
implements를 사용해서도 상속할 수 있다. 하지만 implements를 사용하면 private이나 protected는 사용할 수 없다.
interface User {
firstName: string;
lastName: string;
sayHi(name: string): string;
fullName(): string;
}
class Player implements User {
constructor(
public firstName: string, // public만 사용 가능
public lastName: string
) {}
fullName() {
return `${this.firstName} ${this.lastName}`;
}
sayHi(name: string) {
return `Hi! ${name}. My name is ${fullName()}`;
}
}
여러 개도 상속받을 수 있다. 인터페이스도 클래스처럼 타입으로 사용할 수 있다.
interface User {
firstName: string;
lastName: string;
sayHi(name: string): string;
fullName(): string;
}
interface Human {
health: number;
}
class Player implements User, Human { // 여러 개 상속 가능
constructor(
public firstName: string,
public lastName: string,
public health: number
) {}
fullName() {
return `${this.firstName} ${this.lastName}`;
}
sayHi(name: string) {
return `Hi! ${name}. My name is ${fullName()}`;
}
}
종합 활용 예제
로컬스토리지 API를 흉내낸 클래스. 타입별로 로컬스토리지를 생성할 수 있게 했다.
그동안 봤던 제네릭, 다형성, 클래스, 인터페이스 등을 이렇게 사용할 수 있다.
interface MyStorage<T> { // 인터페이스
[key: string]: T;
}
class LocalStorage<T> { // 클래스, generic의 상속
private Storage: MyStorage<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 stringStorage = new LocalStorage<String>(); // 다형성
stringStorage.get('x');
stringStorage.set("hello", "hi")
const booleanStorage = new LocalStorage<Boolean>();
booleanStorage.get('x');
booleanStorage.set("hello", true) // 설정한 것에 따라 다른 타입의 인수를 받음
'유튜브 강의' 카테고리의 다른 글
[코딩앙마] 타입스크립트 1. 기본 타입 (0) | 2022.10.24 |
---|---|
[Styled Components] Styled Components (feat. 노마드코더) (4) | 2022.08.28 |
[노마드코더] 타입스크립트로 블록체인 만들기 2. 타입스크립트 문법_함수 (0) | 2022.08.25 |
[노마드코더] 타입스크립트로 블록체인 만들기 1. 타입스크립트 문법_타입 (0) | 2022.08.22 |
코딩앙마 자바스크립트 중급 강의 12. 클래스(Class) (0) | 2022.08.10 |
- Total
- Today
- Yesterday
- 김버그
- vscode
- map
- 드림코딩
- 제이쿼리
- scss
- 코딩앙마
- js
- 저스트코드
- javascript
- 자바스크립트
- TS
- 구름에듀
- CSS
- Typescript
- 깃
- 리액트
- git
- 제로초
- 타입스크립트
- vue
- 파이썬
- 회고
- 스파르타코딩클럽
- 코드잇
- Python
- Til
- React
- 비주얼스튜디오코드
- html
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |