4.0 Classes
(1) Constructor
Js와 마찬가지로 Ts에서도 필드를 생성할 때 constructor함수를 사용한다.
동일한 코드를 Js와 Ts로 적어보겠다
//Js
class Player{
constructor(
this.Firstname: string,
this.Lastname: string,
this.nickname: string
){}
}
//Ts
class Player{
constructor(
private Firstname: string,
private Lastname: string,
public nickname: string
){}
}
this. : Js로 필드를 선언할 때는 this라는 키워드를 계속 입력해야 한다.private, public: 접근할 수 있는 범위에 따라서 지정하는 것으로 Ts에서만 존재하는 문법이다private: Class 내부에서만 접근 가능하다. Class 외부에서는 수정뿐아니라, 읽어들이는 것도 불가능하다.public: Class 외부에서 접근이 가능하다. 읽어들이는 것은 물론 수정도 가능하다.
이렇게 생성한 class 를 호출하여 사용하는 방법은 다음과 같다
class Player{
constructor(
private Firstname: string,
private Lastname: string,
public nickname: string
){}
}
const pongdang = new Player("pong", "dang", "pungdung");
new Player: 내가 작성하고 싶은 class이름 앞에 new라는 키워드를 적어서 표현해준다"pong", "dang", "pungdung": constructor를 통해서 만들었던 필드에 차례로 값을 부여해준다.- 따라서 지금은 firstname 에 pong, Lastname에 dang 이런식으로 들어가고 있는 것이다.
(2) Abstract Class
Class를 여러 개 만들 때 중복되는 부분이 많은 경우 매번 복붙을 해야 하니 귀찮다. 따라서 Abstract class를 만들었다. 이는 확장이 가능한 class로 직접 사용은 불가능하지만, 확장판으로써 사용할 수는 있다.
abstract class Player={
constructor{
private Fisrtname : string,
private Lastname : string,
public nicknake : string
}()
}
class User extends Player ={
}
User.nickname//can't
abstract class: 처음부터 선언할 때 abstract class라고 선언해야 함. 이 외의 모든 선언은 동일extends Player: 내가 확장하고 싶은 abstract class를 먼저 써주고 extends라는 키워드를 작성해준다.User: 새로운 class의 이름이다. 이렇게 되면 Player라는 abstract class의 속성을 모두 받아오게 된다.
따라서 지금까지는 abstract class를 선언하고, 이를 확장하여 class를 선언하는 방식에 대해 배웠다.
(3) Ordinary && abstract method
지금까지는 class를 abstract로 선언하는 방법에 대해서만 배웠다. 그런데 class안의 메소드도 abstract하게 선언할 수 있을까?
우선 일반 메소드를 abstract class안에 선언하여 확장하는 방법에 대해 알아보자.
abstract class Player={
constructor{
private Fisrtname : string,
private Lastname : string,
public nicknake : string
}();
getFullName(){
return `${this.Firstname} ${this.Lastname}`
}
}
class User extends Player {
}
getFullName: 일반적인 메소드로, class안에 있는 private 필드에 접근하여 전체 이름을 리턴하고 있다.
이런식으로 메소드를 선언하여 클래스를 확장하면 User.getFullName() 과 같이 함수를 호출하여 메소드를 사용할 수 있다.
그렇다면 abstract Method란 뭘까? 우선 abstract Method는 여러 개의 조건을 만족해야 한다.
abstract class안의method여야 한다.- 함수의 구현 (=implement)를 작성하지 않는다
abstract class를 확장해서 쓰는 class들(ex| User)가 함수를 반드시 정의내리고 사용해야 한다.
직접 쓰면서 확인해보자
abstract class Player={
constructor{
private Fisrtname : string,
private Lastname : string,
public nicknake : string
}();
getFullName(){
return `${this.Firstname} ${this.Lastname}`
}
abstract getNickname():void
}
class User extends Player{
getNickname(){
console.log(this.nickname);
}
}
abstract: abstract라고 적고 함수 이름을 작성한다getNickname():void : 함수를 적고, 이 함수의 return값 종류를 적어준다. call signiture랑 유사하다.getNickname(){…}: User 안에서 Player class안의 abstract method를 정의내리고 시작해야 한다.
하지만 지금 위에 적은 코드는 public필드에 접근하고 있어서 문제가 없지만, firstname, lastname에는 접근할 수 있다는 한계가 있다. 아무리 Player를 extend해서 사용하는 User라고 해도, private 필드에 접근이 불가능하다. 이런 문제를 해결해보자.
(4) Protected
Protected라는 키워드를 private 라는 키워드랑 비교해보자
즉 protected를 사용하면 외부에서 접근은 불가능하지만, 상속 받은 자식들은 접근이 가능한 것이다.
abstract class Player={
constructor{
protected Fisrtname : string,
protected Lastname : string,
public nicknake : string
}();
getFullName(): string,
abstract getNickname():void
}
class User extends Player{
getNickname(){
console.log(this.nickname);
}
getFullName(){
return `${this.Firstname} ${this.Lastname}`
}
}
4.2 Recap - make a dictionary
(1) Make a dictionary
class dict={
constructor{
word: string
}()
}
근데 나는 여러 개의 단어를 저장하고 싶다. 다양한 단어가 단어 : 정의 형태로 묶여있는 class를 만들고 싶은 것이다.
const dict={
'potato':'gamja',
'carrot': 'dangeun'
}
이렇게 변수의 이름 (potato, carrot)은 모르지만, 변수 이름의 자료형과, 이 변수가 가지는 값을 아는 경우 class를 어떻게 선언해야 할까?
(→ 변수 이름 && 변수의 자료형만 아는 경우 but 이름은 모르는 경우)
type Words={
[key:string]:string
}
class dict : Words={
'potato':'gamja',
'carrot': 'dangeun'
}
[key:string]:string:- []안에는 변수 이름을 임시로 작성해준다(=key) 실제 변수 이름과는 무관하다.
- 이후 변수 이름의 자료형과, 변수의 자료형을 명시해준다
: Words: 변수 이름과, 변수타입이 고정된 class를 선언할 것이다.
이렇게 type과 class를 선언하면 변수의 이름을 모르는 경우에도 작성이 가능하다.
(2) Errors in Constructor
정확히 말하면 constructor를 사용했을 때 원하는 결과가 나오지 않는 경우에 대해 말해보겠다.
메소드가 아닌, 필드를 선언할 때는 대부분 constructor를 활용하여 선언하였다. 그런데 기초적인 자료형이 아니라, 내가 원하는 자료형을 선언하고 싶은 경우에는 어떻게 해야 하는가
class Dict{
constructor(){
this.Words
}
}
내가 Words라는 custom자료형을 사용하고 싶은 상황에서 저렇게 적으면 Ts가 마음대로 words의 자료형을 판단해버릴 것이다. 이렇기에 consturctor위에서 자료형을 명시해주어야 한다.
type Words={
[key:string]:string
}
class Dict{
private words: Words//words는 Word라는 type을 따르는 변수다.
constructor(){
this.words={}
}
}
1.words:Words : constructor밖에서 변수를 선언하고, type을 명시한다.
2. this.words : Words라는 type을 가진 변수를 명시했으므로 words라는 객체를 선언한 것이다.
결국 외부에서 type을 선언하고, 이를 class안으로 끌고 들어오며 이 type으로 이뤄진 객체를 선언하는 방법에 대해 알게 되었다.
이제 words라는 객체안의 word라는 필드를 구성해보자.
(3) word
class Word{//element
constructor(
public term :string,
public def :string
){}
}
const kimchi=new Word("kimchi","Korean Food");
Word: Word 라는 객체 안에는 term과 def라는 필드가 존재한다.new Word: kimchi라는 변수에 word형식의 class를 부여했다.
(4) method to add
이런 word를 추가할 수 있는 method를 생성해보려고 한다.
type Words={
[key:string]:string
}
class Word{//element
constructor(
public term :string,
public def :string
){}
}
class Dict{
private words: Words
constructor(){
this.Words={}//list
}
add(word:Word){
if(this.words[word.term]===undefined){
this.words[word.term]=word.def;
}
}
}
add(word:Word): Word라는 객체를 받아 실행시키는 add 함수를 선언할 것임if(… undefined):this.words[]: 위에서 생성했던 words객체의 어떤 멤버word.term: word의 term 요소this.words[word.term]- 정리하면, 아까 만든 words라는 객체에 word.term 즉 parameter로 보낸 단어가 없다면
this.words[word.term]=word.def: words라는 객체 안에 term이라는 이름을 가진 필드를 만들거고, 이 필드의 값은 word.def일 것임words={ … word.term: word.def }
호출해서 사용할 때는 이렇게 할 수 있다
const dict = new Dict();
dict.add("kimchi", "koreanFood");
이렇게 add method를 사용하면 kimchi: koreanFood라는 요소가 words라는 객체에 만들어졌을 것이다.
(5) Other methods
// delete method
class Dict{
private words: Words
constructor(){
this.Words={}//list
}
add(word:Word){
if(this.words[word.term]===undefined){
this.words[word.term]=word.def;
}
}
add(word:Word){
if(this.words[word.term]===undefined){
this.words[word.term]=word.def;
}
}
Delete(word:Word){
if(this.words[word.term]===undefined){
delete this.words[word.term];
}
}
update(word:Word, newdef : string){
if(this.words[word.term]===undefined){
this.words[word.term]=newdef;
}
}
}'프로그래밍 > Typescript' 카테고리의 다른 글
| TypeError: prevState.boardId is not iterable (0) | 2025.03.20 |
|---|---|
| #4-2 Interfaces (0) | 2025.01.20 |
| #3. Functions (0) | 2025.01.14 |
| #2. Overview of the Typescript (1) | 2025.01.14 |
| Intro (0) | 2025.01.14 |