CodeBox CodeBox

【Typescript】クラスの継承・オーバーライドについて考える【オブジェクト指向】

Typescript / JS
けい

概要

Typescriptでクラスの継承する方法を解説していきます。継承することで同じコードを何度も書かずに済みます。

親クラスBicycleを作成する

constructorの引数にはオブジェクトを渡すようにすると、インスタンスを作成する際に引数の順番を考えずに済み、ミスを防げます。

interface Argument {
  size?: number;
  chain?: string;
  tire_size?: number;
  flag?: string;
}

class Bicycle {
  protected size: number;
  protected chain: string;
  protected tire_size: number;

  constructor(args: Argument = {}) {
    this.size = args.size;
    this.chain = args.chain || this.default_chain();
    this.tire_size = args.tire_size || this.default_tire_size();
  }

  spares() {
    return { tire_size: this.tire_size, chain: this.chain };
  }

  default_chain(): string {
    return "10-speed";
  }

  default_tire_size() {
    return 100;
  }
}


サブクラスRoadBikeを作成する

Bicycleクラスを継承します。サブクラスでは独自のchainとflagを定義しています。

class RoadBike extends Bicycle {
  readonly flag: string;

  constructor(args: Argument) {
    super(args);
    this.chain = "child chain";
    this.flag = args.flag;
  }

  // オーバーライド
  spares() {
    return { tire_size: this.tire_size, chain: this.chain, flag: this.flag };
  }
}

const r = new RoadBike({ flag: "orange" });
console.log(r.spares());

## 実行結果
{ tire_size: 100, chain: 'child chain', flag: 'orange' }


親クラスを継承した場合、constructor内でsuperメソッドを実行する必要があります。仮にsuperの記述を書くのを忘れた場合何が起きるのでしょうか?

class RoadBike extends Bicycle {
  readonly flag: string;

  constructor(args: Argument) {
    this.chain = "child chain";
    this.flag = args.flag;
  }
(以下省略)

const r = new RoadBike({ flag: "orange" });
console.log(r.spares());

## 実行結果
{ tire_size: undefined, chain: 'child chain', flag: 'orange' }


tire_sizeの中身がundefinedになっています。これは親クラスの変数をしっかり継承できていないためです。

ただTypescriptの場合、下記のような警告文が出るためsuperが必要なことに気付きますね。

ABOUT ME

けい
ベンチャーのフロントエンジニア。 主にVueとTypescriptを使っています。ライターのための文字数カウントアプリ:https://easy-count.vercel.app/