抽象クラス

4 min読了の目安(約2600字TECH技術記事

はじめに

JavaScriptにはなく、TypeScriptに導入された機能の一つに抽象クラスがあります。
クラスについては以前記事(クラスと継承)にしましたので、読んでいただけると幸いです!


抽象クラスの使い方

//抽象クラス
abstract class Person {
  constructor(protected readonly name: string, public age: number) {}
  abstract hello(): void;
}

クラスの前にabstract修飾子がついています。この一行目からPersonクラスは抽象クラスだと判断できます。
またhelloメソッドにもabstract修飾子がついています。
これが意味するのは、Personクラスを継承したサブクラス(以下Japaneseクラス)はhelloメソッドを書くことを強制されます

abstract class Person {
  constructor(protected readonly name: string, public age: number) {}
  abstract hello(): void;
}

class Japanese extends Person {//エラー(非抽象クラス 'Japanese' はクラス 'Person' からの継承抽象メンバー 'hello' を実装しません。)
  //継承先 extends 継承元
  constructor(name: string, age: number, private gender: "male" | "female") {
    super(name, age); //superメソッドで継承元のプロパティを継承先でも使える状態にします。
    this.gender = gender; //継承元のプロパティを受け継いだあとにJapanese独自のプロパティを設定。
  }
}

サブクラスでは、helloメソッドがないとエラーが発生します。

よってJapaneseクラスではPersonクラスのhelloメソッドの型指定に沿ったhelloメソッドを記述する必要があります。

abstract class Person {
  constructor(protected readonly name: string, public age: number) {}
  abstract hello(): void;
}

class Japanese extends Person {
  //継承先 extends 継承元
  constructor(name: string, age: number, private gender: "male" | "female") {
    super(name, age); //superメソッドで継承元のプロパティを継承先でも使える状態にします。
    this.gender = gender; //継承元のプロパティを受け継いだあとにJapanese独自のプロパティを設定。
  }
  hello() {
    console.log("konnichiwa" + this.name); //←継承元のメソッドを上書きすることができます。
  }
}

const takashi = new Japanese("Takashi", 24, "male");
takashi.hello(); //konnichiwaTakashi

抽象クラスの注意点

①抽象メソッドに実装を含めることはできない

抽象クラスに定義した抽象メソッドに値レベルのコードを書くことはできません

abstract class Person {
  constructor(protected readonly name: string, public age: number) {}
  abstract hello() {//エラー(メソッド 'hello' は abstract に指定されているため、実装を含めることができません。)
    console.log("hello");
  }
}

抽象メソッドには型レベルのコードしか受け付けません

②抽象クラスをインスタンス化できない

抽象クラスであるPersonを直接インスタンス化しようとすると、Typescriptはエラーを出します。

abstract class Person {
  constructor(protected readonly name: string, public age: number) {}
  abstract hello(): void;
}
const bob = new Person();//エラー(抽象クラスのインスタンスは作成できません。)

abstractによって、抽象クラスを継承したサブクラスからインスタンス化できるように強制させます。


言葉の整理

・abstractが指定され、インスタンス化できない、継承元のクラスを抽象クラスという。(今回の例ではPersonクラス)
・抽象クラスを継承したサブクラスを具象クラスという。(今回の例ではJapaneseクラス)
・抽象クラスには実装しない(型の指定のみ行う)が、抽象クラスを継承した具象クラスには必ず実装しないといけないメソッドや値を抽象メンバという。(今回の例ではhelloメソッド)