PracticeEveryday

Class 본문

JavaScript/TypeScript

Class

kimddakki 2022. 8. 3. 17:58
1. 클래스 정의

 - ES6 클래스는 몸체에 메소드만을 포함할 수 있다. 클래스 몸체에 클래스 프로퍼티를 선언할 수 없고 반드시

   생성자 내부에서 클래스 프로퍼티를 선언하고 초기화한다.

// person.js
class Person {
  constructor(name) {
    // 클래스 프로퍼티의 선언과 초기화
    this.name = name;
  }

  walk() {
    console.log(`${this.name} is walking.`);
  }
}

이 코드의 확장자를 .ts로 바꾸어 컴파일하면 에러가 난다.

person.ts(4,10): error TS2339: Property 'name' does not exist on type 'Person'.
person.ts(8,25): error TS2339: Property 'name' does not exist on type 'Person'.

※ TypeScript 클래스는 클래스 몸체에 클래스 프로퍼티를 사전 선언하여야 한다.

class Person {
  // 클래스 프로퍼티를 사전 선언하여야 함
  name: string;
  constructor(name: string) {
    // 클래스 프로퍼티에 값을 할당함.
    this.name = name;
  }

  walk() {
    console.log(`${this.name} 걷는 중 ..`)
  }
}

 

2. 접근 제한자

 - TypeScript 클래스는 클래스 기반 객체 지향 언어가 지원하는 접근 제한자 ( Access modifier )

   public, private, protected를 지원하며 의미 또한 기본적으로 동일하다.

 

 - 접근 제한자를 명시하지 않을 때

타 클래스 기반 언어 : 암묵적으로 protected로 지정

타입스크립트 : 암묵적으로 public 선언

 

 - 접근 제한자를 선언한 프로퍼티와 메소드에 대한 접근 가능성

접근 가능성publicprotectedprivate

접근 가능성 public protected private
클래스 내부
자식 클래스 내부
클래스 인스턴스
class Foo {
  public x: string;
  protected y: string;
  private z: string;

  constructor(x: string, y: string, z: string) {
    // public, protected, private 접근 제한자 모두 클래스 내부에서 참조 가능하다.
    this.x = x;
    this.y = y;
    this.z = z;
  }
}

const foo = new Foo("x", "y", "z");

// public 접근 제한자는 클래스 인스턴스를 통해 클래스 외부에서도 참조가 가능하다.
console.log(foo.x);

// protected 접근 제한자는 클래스 인스턴스를 통해 클래스 외부에서 참조할 수 없다.
console.log(foo.y);

// private 접근 제한자는 클래스 인스턴스를 통해 클래스 외부에서 참조할 수 없다.
console.log(foo.z);

class Bar extends Foo {
  constructor(x: string, y: string, z: string) {
    super(x, y, z);
    // public 접근 제한자는 자식 클래스 내부에서 참조 가능하다.
    console.log(this.x);

    // protected 접근 제한자는 자식 클래스 내부에서 참조 가능하다.
    console.log(this.y);

    // private 접근 제한자는 자식 클래스 내부에서 참조 할 수 없다.
    console.log(this.z);
  }
}

 

3. 생성자 파라미터에 접근 제한자 선언

 - 접근 제한자는 생성자 파라미터에도 선언할 수 있다.

 - 이 때 접근 제한자가 사용된 생성자 파라미터는 암묵적으로 프로퍼티로 선언되고 생성자 내부에서 별도의 초기화가

   없어도 암묵적으로 초기화가 수행된다.

 

 - 이 때 private 접근 제한자가 사용되면 클래스 내부에서만 참조 가능하고 public 접근 제한자가 사용되면 클래스 

   외부에서도 참조가 가능하다.

class Foo2 {
  // 접근 제한자가 선언된 생성자 파라미터 x는 클래스 프로퍼티로 선언되고 자동 초기화 된다.
  // public으로 선언되었으므로 x는 클래스 외부에서도 참조가 가능하다.
  constructor(public x: string) {}
}

const foo2 = new Foo2("Hello");
console.log(foo2); // {x : "Hello"}
console.log(foo2.x); // Hello

class Bar2 {
  // 접근 제한자가 선언된 생성자 파라미터 x는 멤버 변수로 선언되고 자동으로 초기화된다.

  // private이 선언되었으므로 x는 클래스 내부에서만 참조 가능하다.
  constructor(private x: string) {}
}

const bar2 = new Bar2("Hello");

console.log(bar2); // { x: "Hello" }
console.log(bar2.x);
//'x' 속성은 private이며 'Bar2' 클래스 내에서만 액세스할 수 있습니다.

 

 - 만일 생성자 파라미터에 접근 제한자를 선언하지 않으면 생성자 파라미터는 생성자 내부에서만 유효한 지역 변수가

   되어 생성자 외부에서 참조가 불가능하게 됩니다.

 

 

class Foo3 {
  constructor(x: string) {
    // 생성자 파라미터는 생성자 내부에서만 유효한 지역 변수이다.
    console.log(x)
  }
}

const foo3 = new Foo3("Hello")
console.log(foo3) // Foo3: {}

 

4. readonly 키워드

 - readonly가 선언된 클래스 프로퍼티는 선언 시 또는 생성자 내부에서만 값을 할당할 수 있다.

 - 그 외에는 값을 할당  할 수 없고 오직 읽기만이 가능한 상태가 된다.

class Foo4 {
  private readonly MAX_LEN: number = 5;
  private readonly MSG: string = "Hello";

  log() {
    this.MAX_LEN = 10;
    // 읽기 전용 속성이므로 'MAX_LEN'에 할당할 수 없습니다
    this.MSG = "Hi";
    // 읽기 전용 속성이므로 'MAX_LEN'에 할당할 수 없습니다
    console.log(`MAX_LEN: ${this.MAX_LEN}`);
    console.log(`MSG: ${this.MSG}`);
  }
}

new Foo4().log();

 

5. static 키워드

 - ES6 클래스에서 static 키워드는 클래스의 정적 ( static ) 메소드를 정의한다.

 - 정적 메소드는 클래스의 인스턴스가 아닌 클래스의 이름으로 호출한다.

  => 인스턴스를 생성하지 않아도 호출할 수 있다.

class Foo {
  constructor(prop) {
    this.prop = prop;
  }

  static staticMethod() {
    /*
    정적 메소드는 this를 사용할 수 없다.
    정적 메소드 내부에서 this는 클래스의 인스턴스가 아닌 클래스 자신을 가리킨다.
    */
    return 'staticMethod';
  }

  prototypeMethod() {
    return this.prop;
  }
}

// 정적 메소드는 클래스 이름으로 호출한다.
console.log(Foo.staticMethod());

const foo = new Foo(123);
// 정적 메소드는 인스턴스로 호출할 수 없다.
console.log(foo.staticMethod()); // Uncaught TypeError: foo.staticMethod is not a function

 

 - TypeScript에서는 static 키워드를 클래스 프로퍼티에도 사용할 수 있다.

 - 정적 메소드와 마찬가지로 정적 클래스 프로퍼티는 인스턴스가 아닌 클래스 이름으로 호출하며 인스턴스를 생성

   하지 않아도 호출할 수 있다.

class Foo5 {
  // 생성된 인스턴스 갯수
  static instanceCounter = 0;

  constructor() {
    Foo5.instanceCounter++;
  }
}

const foo5 = new Foo5();
const foo52 = new Foo5();

console.log(Foo5.instanceCounter);
console.log(foo5.instanceCounter);
// 'instanceCounter' 속성이 'Foo5' 형식에 없습니다. 대신 정적 멤버 'Foo5.instanceCounter'에 액세스하려고 하셨습니까?

 

6. 추상 클래스

 - 추상 클래스 ( abstract class )는 하나 이상의 추상 메소드를 포함하며 일반 메소드도 포함할 수 있다.

 - 추상 메소드는 내용이 없이 메소드 이름과 타입만이 선언된 메소드를 말하며 선언할 때 abstract 키워드를 사용한다.

 - 추상 클래스를 정의할 때는 abstract 키워드를 사용하며, 직접 인스턴스를 생성할 수 없고 상속만을 위해 사용한다.

 - 추상 클래스를 상속한 클래스는 추상 클래스의 추상 메소드를 반드시 구현해야 한다.

 

abstract class Animal {
  // 추상 메소드
  abstract makeSound(): void;

  move(): void {
    console.log("roaming the earth ...");
  }
}

// 직접 인스턴스를 생성할 수 없다.
new Animal();
// 추상 클래스의 인스턴스를 만들 수 없습니다.

class Dog extends Animal {
  // 추상 클래스를 상속한 클래스는 클래스의 추상 메소드를 반드시 구현해야 한다.
  makeSound() {
    console.log("Bowwow~!");
  }
}

const dog1 = new Dog();
dog1.makeSound();
dog1.move();

 

 - 인터페이스는 모든 메소드가 추상 메소드이지만 추상 클래스는 하나 이상의 추상 메소드와 일반 메소드를 포함할

   수 있다!

 


 

 

TypeScript - Class | PoiemaWeb

ES6에서 새롭게 도입된 클래스는 기존 프로토타입 기반 객체지향 언어보다 클래스 기반 언어에 익숙한 개발자가 보다 빠르게 학습할 수 있는 단순명료한 새로운 문법을 제시하고 있다. 하지만

poiemaweb.com

 

'JavaScript > TypeScript' 카테고리의 다른 글

TypedI  (0) 2022.08.25
TypeScript  (0) 2022.06.14
TypeScript  (0) 2022.06.10
TypeScript  (0) 2022.06.10
TypeScript  (0) 2022.06.04
Comments