TypeScript

【TypeScript】クラスの継承とその記述方法について初心者向けにまとめてみた

TypeScript

 

今回はTypeScriptのにおけるクラスの継承とその記述方法について解説したいと思います。クラスの継承をうまく使うことで同じコードをいくつも書く必要がなく新しいクラスを定義することが可能です。

クラスの継承はチーム開発をする際に特に重要な概念になってくるので、この機会に理解を深めていきましょう。

TypeScriptに関わらず、オブジェクト指向の言語では共通の手法だね。

クラスの継承とは

クラスの継承とは、あるクラスが他のクラスの特性を引き継ぐことです。継承される既存のクラスをスーパークラス(親クラス)、継承した新しく作ったクラスをサブクラスと言います。

Wikipediaには継承について以下のように記載されています。

継承(けいしょう、inheritance:インヘリタンス)とはオブジェクト指向を構成する概念の一つである。あるオブジェクトが他のオブジェクトの特性を引き継ぐ場合、両者の間に「継承関係」があると言われる。一般的に、BがAを継承する場合、B is a A. (BはAの一種である)という意味的な関係(Is-a関係)が成り立つ。従って、同じふるまいを持つからと言って、意味的に無関係なクラス間に継承関係を持たせるのは適切でない場合が多い。

参考:Wikipedia

 

継承のメリットとしては、以下の2つが挙げられます。

  • コードの重複を減らすことで、可読性や再利用性を高めることができる
  • メソッドの追加やオーバライドをすることで自由に拡張することができる

コードで見てみる

上記の説明だけでは腑に落ちない方もいると思うので、実際のコードでも見てみましょう。クラスの継承はオブジェクト指向全体の概念ですが、今回はTypeScriptに焦点を当てて見ていきます。

以下は基本的なクラス宣言をしたコードになります。変数にはアクセス修飾子「private」を付与しています。

class Fruits {
  constructor(private _fruitsname: string) {
  }

  say(): void {
    console.log("好きなフルーツは" + this._fruitsname + "です。")
  }
}
TypeScript
【TypeScript】ゲッター(getter)とセッター(setter)についての理解を深めるTypeScriptにおけるゲッター(getter)とセッター(setter)について解説しています。アクセス修飾子「privare」を付与した場合、外部から値を呼び出すことや取得することができなくなります。しかし、そういった時にゲッターとセッターを定義することで呼び出しと取得が可能になります。...

 

ここからFruitsクラスに定義されている変数やメソッドを保持したまま、新しいクラスを定義したかったとします。その場合は「extends」というオプションを付け、新しいクラスを定義しましょう。

class Fruits {
  constructor(private _fruitsname: string) {
  }

  say(): void {
    console.log("好きなフルーツは" + this._fruitsname + "です。")
  }
}

class AnotherFruits extends Fruits {
}

 

先ほど定義したクラス(AnotherFruits)に新たに変数を定義してみます。今回はcolorというprivate変数を新たに定義しました。

class Fruits {
  constructor(private _fruitsname: string) {
  }

  say(): void {
    console.log("好きなフルーツは" + this._fruitsname + "です。")
  }
}

class AnotherFruits extends Fruits {
  private _color: string;
}

 

続いてコンストラクタを新たに定義します。コンストラクタに渡される引数はfruitsnameとcolorの2つにします。

class Fruits {
  constructor(private _fruitsname: string) {
  }

  say(): void {
    console.log("好きなフルーツは" + this._fruitsname + "です。")
  }
}

class AnotherFruits extends Fruits {
  private _color: string;

  constructor(_fruitsname: string, _color: string) {
    super(_fruitsname);
    this._color = _color
  }
}
superを記述することで、親クラスの変数(今回の場合は変数fruitsname)を呼び出すことができます。

 

次にメソッドを定義します。今回は同じ名前のメソッド名を定義し、メソッドのオーバーライドを行います。今回も同様に「super.say();」とすることで、superを使用し、親クラスのメソッドを呼び出しています。

class Fruits {
  constructor(private _fruitsname: string) {
  }

  say(): void {
    console.log("好きなフルーツは" + this._fruitsname + "です。")
  }
}

class AnotherFruits extends Fruits {
  private _color: string;

  constructor(_fruitsname: string, _color: string) {
    super(_fruitsname);
    this._color = _color
  }

  say(): void {
    super.say();
    console.log("その色は" + this._color + "です。")
  }
}
メソッドのオーバーライドとはそのままの通り、メソッドを上書きすることを言います。

 

ではここでインスタンスの生成とメソッドの呼び出しを行ってみましょう。

class Fruits {
  constructor(private _fruitsname: string) {
  }

  say(): void {
    console.log("好きなフルーツは" + this._fruitsname + "です。")
  }
}

class AnotherFruits extends Fruits {
  private _color: string;

  constructor(_fruitsname: string, _color: string) {
    super(_fruitsname);
    this._color = _color
  }

  say(): void {
    super.say();
    console.log("その色は" + this._color + "です。")
  }
}

var favorite = new AnotherFruits("バナナ", "黄色");
=> 好きなフルーツはバナナです。

favorite.say();
=> その色は黄色です。

 

上記コードをコンパイルし、実行することで予想される結果「好きなフルーツはバナナです。」と「その色は黄色です。」が出力されると思います。

これがクラスの継承の基本的な流れになります。

まとめ

  • クラスの継承とは、あるクラスが他のクラスの特性を引き継ぐことである。
  • 継承される既存のクラスをスーパークラス(親クラス)、継承した新しく作ったクラスをサブクラスと言う。
  • クラスの継承を行うには「extends」というオプションを付与する必要がある。
  • superを記述することで、親クラスの値を呼び出すことができる。
  • メソッドのオーバーライドとは、メソッドを上書きすることを言う。

参考

TypeScript プログラミング 継承:
https://docs.solab.jp/typescript/class/inheritance/

オブジェクト指向「継承」とは?わかりやすく解説してみた:
https://www.sejuku.net/blog/9598

 

 

今回はTypeScriptのにおけるクラスの継承とその記述方法について解説しました。継承をうまく使い、重複を避けた綺麗なコードになるよう心がけていただけたらと思います。