TypeScriptチートシート２（クラス）


<h2>1:クラス</h2>

```typescript
class Person {
  name: string;
  constructor(initName: string) {
    this.name = initName;
  }
}

const suda = new Person('masaki');
```

<h2>2:this</h2>
メソッドはアロー関数で書かない方がいい

```typescript
class Person {
  name: string;
  constructor(initName: string) {
    this.name = initName;
  }

  greeting(this: { name: string }) {
    console.log(`hello,${this.name}`);
  }
}
```

<h2>3:クラスを型としてつかう</h2>
クラスを定義するのはオブジェクトの型も同時に定義している

```typescript
class Person {
  private name: string;
  private age: number;
  constructor(initName: string, initAge: number) {
    this.name = initName;
    this.age = initAge;
  }
  incrementAge() {
    this.age += 1;
  }
  greeting(this: Person) {
    console.log(`hello,${this.name},${this.age}yearsOld`);
  }

  //↑↓は同じ意味　クラスを型として使えば、プロパティが増えても書き直す必要ない

  // greeting(this: { name: string; age: string }) {
  //   console.log(`hello,${this.name},${this.age}yearsOld`);
  // }
}

let person: Person;

const suda = new Person('masaki');
```

<h2>4:private,public</h2>
・private そのクラスでのみアクセス可能
・protected そのクラスとサブクラスでのみアクセス可能
・public どこからでもアクセス可能(デフォルト)

```typescript
class Person {
  public name: string;
  private age: number;
  constructor(initName: string, initAge: number) {
    this.name = initName;
    this.age = initAge;
  }
  incrementAge() {
    this.age += 1;
  }
  greeting(this: Person) {
    console.log(`hello,${this.name}`);
  }
}
```

<h2>5:readonly</h2>
クラスの中でも外でも読むだけ

```typescript
class Person {
  readonly name: string;
  readonly age: number;
  constructor(initName: string, initAge: number) {
    this.name = initName;
    this.age = initAge;
  }
  //   incrementAge() {
  //     this.age += 1;
  //   }
  greeting(this: Person) {
    console.log(`hello,${this.name}`);
  }
}
```

<h2>6:extends</h2>
constructorの引数を増やしたかったらsuper()を使う

```typescript
class Teacher extends Person {
  constructor(name: string, age: number, public subject: string) {
    super(name, age);
  }
}

const teacher = new Teacher('masaki', 28, 'English');
```

<h2>7:getter,setter</h2>
・getter
データを取得した時に処理を実行
・setter
変更した時に処理を実行

関数名は同じにできる

```typescript
class Teacher extends Person {
  get subject() {
    if (!this._subject) {
      throw new Error('no subject');
    }

    return this._subject;
  }

  set subject(value) {
    this._subject = value;
  }
  constructor(name: string, age: number, public _subject: string) {
    super(name, age);
  }
}

const teacher = new Teacher('masaki', 28, 'English');
//getter
teacher.subject;
//setter
teacher.subject = 'Math';
```

<h2>8:abstract</h2>
abstractがついたクラスはインスタンス化できない
サブクラスを作るためのクラス

```typescript
abstract class AbstractClass {
  protected constructor(private name: string, protected old: number) {}

  showInfo(): void {
    console.log(`name: ${this.name}, ${this.showDetail()}`);
  }

  //このクラスを継承したクラスはshowDetailメソッドを持つ必要がある
  //戻り値の型もしっかり定義
  protected abstract showDetail(): string;
}

class ExtendedClass extends AbstractClass {
  constructor(name: string, old: number, private weight: number) {
    super(name, old);
  }

  showDetail(): string {
    return `old: ${this.old}, weight: ${this.weight}`;
  }
}

const extendedClass = new ExtendedClass('ジョン', 3, 20);
extendedClass.showInfo(); // name: ジョン, old: 3, weight: 20
```

<h2>9:シングルトンパターン</h2>
クラスからインスタンスを1つしか作れなくする

１：コンストラクターに private をつけ外部からアクセスできないように（インスタンス化できない）する
２：static メソッドを作成
３：static プロパティを作成
４：static メソッドの中でインスタンス化をし、static プロパティに代入
５：static メソッドの中ですでにインスタンス化されていたらそれをそのまま返す

```typescript
class Teacher extends Person {
  private static instance: Teacher;
  explainJob() {
    console.log(`I am a teacher and I teach ${this.subject}.`);
  }
  get subject(): string {
    if (!this._subject) {
      throw new Error('There is no subject.');
    }
    return this._subject;
  }
  set subject(value) {
    if (!value) {
      throw new Error('There is no subject.');
    }
    this._subject = value;
  }
  private constructor(name: string, age: number, private _subject: string) {
    super(name, age);
  }
  static getInstance() {
    if (Teacher.instance) return Teacher.instance;
    Teacher.instance = new Teacher('Quill', 38, 'Math');
    return Teacher.instance;
  }
}
const teacher = Teacher.getInstance();
const teacher2 = Teacher.getInstance();
console.log(teacher, teacher2);
//同じものが返る
```