TIL

23/12/20 TIL __ typescript 접근 제어자와, 추상 클래스

GABOJOK 2023. 12. 21. 00:05

 

 

타입스크립트 강의를 듣다가 헷갈리는 부분을 위주로 정리한다.

 

오버라이드

  • 상위클래스에서 정의한 함수를 자식클래스에서 재정의 하는것

 

접근제어자 

  • public : 디폴트 값. 어디서나 접근가능
  • protected: 상속받은 하위 클래스만 접근 가능
  • private: 선언한 클래스 내에서만 접근 가능하다 _ 정보 은닉에 좋다. 

 

 

// protected 접근 제어자는 상속받은 하위클래스에서만 접근이 가능하다.
// class Input {
//   protected name: string;
//   constructor(name: string) {
//     this.name = name;
//   }
//   protected inputName() {
//     console.log(`input name is ${this.name}`);
//   }
// }
// const input = new Input("input");
//console.log(input.inputName())  이거는 에러가난다.
// 왜냐하면, protected 라는 접근제어자를 붙여줬기 때문에 상속받은 하위클래스 에서만 접근이 가능하기 때문에

//그래서 아래와 같이 한다.
// class Button extends Input{
//   constructor(name: string){
//     super(name)
//   };
//   inputName(){
//     console.log(`button name is ${this.name}`)
//   }
// }

// const button: Input = new Input('button'); //에러남. protected 접근자 때문에,
// const button: Input = new Button('button');//이렇게 button이라는 애를 이용해서 출력하게 되면, protected 접근자가 있는 부모 클래스가 아닌,
//자식 클래스를 이용해서 호출하기 때문에 정상적으로 호출이 된다.

//추상클래스와 차이점을 보자면?
//추상 클래스도 상속을 위한 클래스 이지만, 추상 클래스는 구현되지 않은 메서드가 존재 할수 있다는게 다르다?

// private __ 캡슐화 구현 위해 씀.
//선언한 클래스 내에서만 접근이 가능하다.
// private 라는 접근자가 있다면 보통 앞에 _ 언더바를 붙이는게 통상적이다.
//이후 외부에서 접근시 get/set을 이용한다.
// private 접근 제어자는 해당 클래스의 인스턴스 내에서만 접근이 가능하도록 제한하는 역할을 하며,
// 클래스의 데이터를 보호하고 외부에서의 무분별한 접근을 방지하는데 사용
//아래 예를 보자면

class Input {
  private _name: string;
  protected constructor(name: string) {
    this._name = name;
  }
  get name(): string {
    return this.name;
  }
  set name(name: string) {
    this._name = name;
  }
}

class Button extends Input {
  constructor(name: string) {
    super(name);
    // console.log(this._name);  Error!
    // TS2341: Property '_name' is private and only accessible within class 'Input'.
  }
}

const button = new Button("my Button");
// get 호출
console.log(`button name is ${button.name}`); // button name is my Button
// set 호출
button.name = "my Button2";
// get 호출
console.log(`button name is ${button.name}`); // button name is my Button2

//readonly 라는건 읽기 전용 이라는 거임.
//이거 붙이면 constant(상수)로 인식되어 생성자에서 한번 결정된 후 변경 불가함.

// static __ 바뀌지 않고 공통적으로 사용될 값 혹은 메서드를 사용할때 사용.
// 지금까지의 변수나 메서드들을 살펴보면 흐름은 인스턴스화 -> 호출
// 그렇지만 인스턴스화가 필요하지 않은 경우도 있다. 예를들면
// 바뀌지않고 공통적으로 사용될 값 혹은 메서드 입니다. ES6 에서는 메서드만 static 을 붙일 수 있었지만 TS 에서는 프로퍼티도 가능합니다.

//추상클래스
//다른 클래스에서 파생될 수 있는. 말그대로 추상적인 클래스.
//abstract 키워드가 클래스 앞에 있으면 추상클래스임.
//추상 클래스 내의 메소드에 abstract  키워드를 붙이면, 파생 클래스에서 반듯이 구현해야함.
//추상 클래스는 new 를 통해 인스턴스 할 수 없다.

//인터페이스와는 다르게 추상 클레스는 멤버에 대한 구현 세부정보를 포함 할 수 있다.

abstract class Job {
  readonly nickname: string;
  constructor(nickname: string) {
    this.nickname = nickname;
  }
  greet(): void {
    console.log(`My nickname is ${this.nickname}`);
  }
  abstract attack(): void;
}
class Warrior extends Job {
  attack() {
    console.log("검을 사용해 공격!");
  }
}
class Magician extends Job {
  attack() {
    console.log("마법을 사용해 공격!");
  }
}
// const job: Job = new Job('what'); Error!
// TS2511: Cannot create an instance of an abstract class.
const warrior: Job = new Warrior("heecheolman");
const magician: Job = new Magician("heecheol");
warrior.greet(); // My nickname is heecheolman
magician.greet(); // My nickname is heecheol
warrior.attack(); // 검을 사용해 공격!
magician.attack(); // 마법을 사용해 공격!

//인터페이스와 추상클래스 (abstract class) ckdl
//인터페이스는 객체의 구조만을 정의하지만, abstract는 클래스의 기본 구현을 제공한다.
//인어페이스는 다중상속 즉 하나의 클래스는 여러 인터페이스를 구현할 수 있지만, abstract는 단일 상속만 지원한다.
//인터페이스는 인터페이스를 구현하는 클래스는 인터페이스에 정의된 모든 메서드를 전부 구현해야 하며,
//추상클래스는 이걸 상속받은 자식 클래스의 경우 반듯이 추상함수를 구현해야만 합니다.
//따라서 기본 구현을 제공하고 상속을 통해 확장하는데 초점을 맞춘다면 추상 클래스,
//객체가 완벽하게 특정 구조를 준수하도록 강제하고자 한다면 인터페이스를 사용하면 된다.

 

 

 

참고한 블로그

https://heecheolman.tistory.com/65