개발하고 싶은 초심자
230227 D+4 OOP(Object Oriented Programming/객체 지향 프로그래밍) in Typescript 본문
기술개념정리(in Typescript)
230227 D+4 OOP(Object Oriented Programming/객체 지향 프로그래밍) in Typescript
정새얀 2023. 2. 27. 16:531. How to create Classes in Typescript
class Profile {
constructor (
private firstName: string,
private lastName: string, // private 필드
public age: number // public 필드
) {}
}
// private keyword는 오직 TS가 보호해주기 위해 사용하는 것임.
const kimcoding = new Profile("coding", "kim", 15);
// 동작하지 않음
// Property 'firstName' is private and only accessible within class 'Profile'.
// 'firstName' 속성은 private이며 'Profile' 클래스 내에서만 액세스할 수 있습니다.
kimcoding.firstName
// 동작하는 코드
kimcoding.age
✅ abstract class(추상 클래스)
: 다른 클래스가 상속받을 수 있는 클래스. 오직 다른 곳에서만 상속받을 수 있는 클래스.
→ 추상 클래스는 직접 새로운 인스턴스를 만들 수 없음.
abstract class User {
constructor (
private firstName: string,
private lastName: string,
public age: number
) {}
}
class Profile extends User {
};
// 동작하지 않는 코드
// Cannot create an instance of an abstract class.
// 추상 클래스의 인스턴스를 만들 수 없습니다.
const kimcoding = new User("coding", "kim", 15);
✅ abstract method(추상 메소드)
: 추상 클래스를 상속받는 모든 것들이 구현해야하는 메소드.
✷ method(메소드): 클래스 안에 존재하는 함수.
abstract class User {
constructor (
private firstName: string,
private lastName: string,
public age: number
) {}
private getFullName() { // add private keyword
return `${this.firstName} ${this.lastName}`;
}
}
class Profile extends User {
};
const kimcoding = new Profile("coding", "kim", 15);
// 동작하지 않음
// 'getFullName' 속성은 private이며 'User' 클래스 내에서만 액세스할 수 있습니다.
kimcoding.getFullName();
// private, public은 property 뿐만 아니라 method에서도 작동하는 것을 알 수 있음
abstract class User {
constructor (
private firstName: string,
private lastName: string,
public age: number
) {}
// 추상 클래스 안에 들어가있는 메소드
// 명시하지 않았지만 기본적으로는 public이다.
getFullName() {
return `${this.firstName} ${this.lastName}`; // 메소드의 구현(implementation)
}
}
class Profile extends User {
};
const kimcoding = new Profile("coding", "kim", 15);
// coding kim
// 추상 클래스에서 메소드를 구현했을 때 상속받는 클래스에서 호출할 수 있음을 알 수 있음.
kimcoding.getFullName();
추상 메소드를 만들려면 메소드를 클래스 안에서 구현하지 않으면 된다.
⇒ 추상 클래스 안에서는 추상 메소드를 만들 수 있지만 메소드를 구현해서는 안되고 메소드의 call signature만 적어두어야 한다.
abstract class User {
constructor (
private firstName: string,
private lastName: string,
private age: number
) {}
abstract getAge(): void // call signature
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
}
// Non-abstract class 'Profile' does not implement inherited
// abstract member 'getAge' from class 'User'.
// 비추상 클래스 'Profile'은(는) 'User' 클래스에서 상속된 추상 멤버 'getAge'을(를) 구현하지 않습니다.
// TS에서 Profile이 getAge를 구현해야한다고 알려주고 있음.
class Profile extends User {
};
// 추상 클래스를 상속받는 클래스에서 추상 메소드를 구현해주어야 한다.
class Profile extends User {
getAge() {
console.log(this.age);
}
};
const kimcoding = new Profile("coding", "kim", 15);
kimcoding.getFullName(); // coding kim
abstract class User {
constructor (
private firstName: string,
private lastName: string,
private age: number
) {}
abstract getAge(): void
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
}
class Profile extends User {
getAge() {
// 앞에서 age를 private property로 만들었기 때문에 동작하지 않는 코드임
// property를 private으로 만들면, 그 클래스를 상속했더라도 그 property에 접근할 수 없음.
// private 필드가 있을 때, properties는 인스턴스 밖에서 접근할 수 없고, 다른 자식 클래스에서도 접근할 수 없음
console.log(this.age);
}
};
private은 User 클래스의 인스턴스나 메소드에서 접근할 수 있지만, User 클래스는 추상 클래스이기 때문에 인스턴스화 할 수 없다.
✅ protected
abstract class User {
constructor (
// change private to protected
protected firstName: string,
protected lastName: string,
protected age: number
) {}
abstract getAge(): void
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
}
class Profile extends User {
getAge() {
console.log(this.age);
}
};
const kimcoding = new Profile("coding", "kim", 15);
// 동작하지 않음
// firstName은 proteced이기 때문에 클래스 밖에서는 접근할 수 없음
// 'firstName' 속성은 보호된 속성이며 'User' 클래스 및 해당 하위 클래스 내에서만 액세스할 수 있습니다.
kimcoding.firstName;
구분 | 선언한 클래스 내 | 상속받은 클래스 내 | 인스턴스 |
private | ⭕ | ❌ | ❌ |
protected | ⭕ | ⭕ | ❌ |
public | ⭕ | ⭕ | ⭕ |
abstract class User {
constructor (
protected firstName: string,
protected lastName: string,
protected age: number
) {}
abstract getAge(): void
protected getFullName() {
return `${this.firstName} ${this.lastName}`;
}
}
class Profile extends User {
getAge() {
// getFullName() 호출 가능
this.getFullName();
console.log(this.age);
}
};
const kimcoding = new Profile("coding", "kim", 15);
// 여전히 에러 메시지는 나옴
kimcoding.getFullName();
만약 age를 외부 모든 곳에서 사용 가능하게 만들려면 protected를 public으로 변경해주면 된다.
✅ age의 속성을 public으로 명시해주지 않았더니, 'Property 'age' does not exist on type 'Profile.'라는 에러 메시지가 떴다.
JS에서 User 클래스는 일반적인 클래스이기 때문에 원한다면 User의 인스턴스를 만들 수 있지만, TS는 허용하지 않는다.
// object의 type을 선언해야할 때 사용할 수 있음
type Tendency = {
// Tendencies의 타입은 string만을 property로 가지는 object임을 의미함
// 제한된 양의 property 혹은 key를 가지는 타입을 정의해주는 방법
// property의 이름은 모르지만 타입만 알고 있을 때 사용함
// 타입은 number, string, boolean ... 뭐든 될 수 있음
[key: string]: string
};
class Mbti {
private tendency: Tendency
constructor() {
this.tendency = {};
}
// 클래스를 타입으로 사용 가능함
add(t: Personality) {
// 주어진 tendency가 Mbti에 존재하지 않는다면(=== undefined)
if(this.tendency[t.term] === undefined) {
this.tendency[t.term] = t.def;
}
}
def(term: string) {
return this.tendency[term];
}
};
class Personality {
constructor(
public term: string,
public def: string
) {}
};
const I = new Personality("Introversion", "내향형");
const mbti = new Mbti();
mbti.add(I);
mbti.def("Introversion");
'기술개념정리(in Typescript)' 카테고리의 다른 글
230226 D+3 호출 시그니쳐(Call Signatures), 오버로딩(overloading), 다형성(polymorphism) (0) | 2023.02.26 |
---|---|
230226 D+3 타입스크립트의 타입들(3) (0) | 2023.02.26 |
230221 D+2 타입스크립트의 타입들(2) (0) | 2023.02.21 |
230221 D+2 타입스크립트의 타입들(1) (0) | 2023.02.21 |
232220 D+1 타입스크립트의 개념과 타입 시스템 (0) | 2023.02.20 |
Comments