VIDEO LESSON
TypeScriptのクラス継承:extends・super・abstractの使い方の解説動画
再生時間 7:35動画を別のタブで開く ↗
動画の字幕・文字起こしを読む
再生中の字幕を濃い黒で表示し、一番上に追従します。字幕の行を選ぶと、その位置から再生できます。
- 0:00こんにちは。
- 0:00今回のテーマは、タイプスクリプトのクラス継承です。
- 0:04継承とは、既存のクラスを土台にして、機能を足した新しいクラスを作る仕組みです。
- 0:10書き方を決めるキーワードは、エクステンズ、スーパー、オーバーライド、プロテクテッド、
- 0:14そしてアブストラクトの五つです。
- 0:18共通の状態や振る舞いは親クラスから引き継げますが、便利さだけで使う仕組みではありません。
- 0:25子クラスは、親クラスとして扱われても困らない、という契約まで引き継ぎます。
- 0:30その点を意識しながら、基本の書き方、親の処理の呼び出し方、情報の渡し方、
- 0:35実装を任せる方法の順に、実行例で確認していきましょう。
- 0:40各ファイルは独立した例として試せるので、一つずつ動かしながら読み進めてください。
- 0:46まず基本形です。
- 0:47パーソンクラスは、読み取り専用の名前を持ち、自己紹介のメソッドを備えています。
- 0:54スチューデントクラスは、エクステンズ・パーソンと書くことで、このクラスを継承します。
- 1:01すると名前と自己紹介は書かなくてもそのまま使え、子クラスでは学籍番号と、
- 1:06学習中であることを返すスタディメソッドだけを足せます。
- 1:12葵と101でインスタンスを作って実行すると、私の名前は葵です、葵は学習中です、
- 1:17学籍番号101、と表示され、記事の期待どおりでした。
- 1:23親の共通部分を一度だけ書き、子では違いに集中できるのが、継承の出発点です。
- 1:29継承で最初につまずきやすいのが、スーパーです。
- 1:33子クラスでコンストラクタを定義する場合、その中でスーパーに引数を渡して、
- 1:38親クラスのコンストラクタを呼び出さなければなりません。
- 1:43先ほどの例では、スーパー・カッコ・名前、として、親が必要とする名前を渡しています。
- 1:49大切な決まりは、ディスを使う前にスーパーを呼ぶことです。
- 1:54順番を逆にして、スーパーより前にディスの名前を読もうとすると、エラー・ティーエス17009などが発生することを、
- 1:59実機でも確認しました。
- 2:05まず親を初期化してから、子の初期化に進む、という順序で覚えてください。
- 2:10次はオーバーライドです。
- 2:12親と同じ名前のメソッドを子クラスに定義すると、振る舞いを置き換えられます。
- 2:17エンプロイークラスでは、イントロデュースをオーバーライドし、親の自己紹介に担当を付け足しています。
- 2:24ここでスーパー・ドット・イントロデュースと呼ぶと、親クラスの実装をそのまま再利用できます。
- 2:30注目点は、変数の型をパーソンと宣言しても、中身がエンプロイーなら子のメソッドが呼ばれることです。
- 2:36実行すると、私の名前は葵です、担当は開発です、と表示され、記事と一致しました。
- 2:41受け取る側は親の型だけを知っていればよい、という使い方につながります。
- 2:46オーバーライドの前にあるオーバーライドという修飾子には、役割があります。
- 2:52親クラスに同じメンバーが本当にあるかを、コンパイラに確認させる印です。
- 2:58さらにノーインプリシットオーバーライドを有効にすると、置き換えているのに印を付け忘れた場合に、
- 3:04エラー・ティーエス4114で知らせてくれます。
- 3:10この設定はストリクトとは別に指定する点にも注意してください。
- 3:15また、親が引数なしで呼べるメソッドに、子で必須の引数を足すような変更は、
- 3:20親の契約に反するためエラー・ティーエス2416になります。
- 3:26なお、型で自動選択されるオーバーロードとは別の概念です。
- 3:31プロテクテッドは、子クラスにだけ必要な情報を渡したいときの修飾子です。
- 3:36例では、ラベル付きアイテムのコンストラクタで、プロテクテッドなラベルを受け取ります。
- 3:43子クラスのメニューアイテムは、そのラベルを使って、角括弧で囲んだ文字列を返すレンダーメソッドを備えています。
- 3:52記事一覧で実行すると、角括弧付きの記事一覧と表示されます。
- 3:57一方、外部のコードからメニュー・ドット・ラベルと直接読むことはできず、エラー・ティーエス2445になることを実機で確認しました。
- 4:07外には隠しつつ、継承先の処理には材料を渡せる、という中間の公開範囲がプロテクテッドです。
- 4:14プライベートとの違いも整理しておきます。
- 4:17プライベートなメンバーは、それを宣言したクラスの中でしか直接参照できません。
- 4:22子クラスからも読めないため、親の内部だけに閉じたい情報に向いています。
- 4:27プロテクテッドは、そこへ継承先まで範囲を広げたものです。
- 4:31どちらも、タイプスクリプトの型チェックによるアクセス制限です。
- 4:35実行時にも本当にプライベートな値が必要な場合は、シャープ付きフィールドという、
- 4:40ジャバスクリプト側の別の仕組みを使います。
- 4:44子に渡す必要があるか、親の中だけに閉じるか、という目的で修飾子を選んでください。
- 4:49アブストラクトクラスは、共通部分だけを先に実装し、具体的な処理を子クラスへ任せたいときの仕組みです。
- 4:57ノーティフィケーションクラスでは、宛先を受け取り、宛先とメッセージを組み合わせるプレビューは親が実装します。
- 5:05一方、メッセージ自体を作るクリエイトメッセージは、アブストラクトなメソッドとして宣言だけで済ませます。
- 5:13ウェルカムノーティフィケーションがそれを実装し、登録ありがとうございます、
- 5:17という文面を返します。
- 5:20実行すると、葵宛、登録ありがとうございます、と表示され、記事と一致しました。
- 5:26なお、この例は表示するだけで、実際の送信は行いません。
- 5:30アブストラクトには、二つの約束があります。
- 5:34一つ目は、抽象クラス自体を直接ニューしてインスタンス化できないことです。
- 5:39試すと、エラー・ティーエス2511になります。
- 5:43土台だけのクラスからは、実物を作らない、という決まりです。
- 5:48二つ目は、具体的な子クラスは、抽象メソッドを必ず実装しなければならないことです。
- 5:54実装を欠いたクラスを書くと、エラー・ティーエス2515で指摘されることを、
- 5:58実機でも確認しました。
- 6:02裏を返せば、必要な実装を書き忘れたまま使えるようにはならないため、共通の手順に差し込む処理を、
- 6:06型の側でそろえられます。
- 6:11最後に、設計の判断です。
- 6:13継承が向いているのは、子クラスを親クラスとして自然に扱える関係です。
- 6:18親を受け取る関数に子を渡しても、引数の条件、戻り値、失敗したときの状態が矛盾しないかを確認してください。
- 6:26子だけが特別な前提を要求すると、親のつもりで使う側が予期しない失敗を起こします。
- 6:32逆に、同じ計算を使いたいだけなら、継承階層を増やす必要はありません。
- 6:37処理を関数や別のオブジェクトに任せる委譲なら、役割ごとに変更とテストを分けられます。
- 6:43階層を深くする前に、変更の影響を追いやすい構成かどうかを立ち止まって考えましょう。
- 6:50迷ったときは、親として扱えるか、という一文でテストすると判断しやすくなります。
- 6:56まとめです。
- 6:56エクステンズで土台を引き継ぎ、スーパーで親を初期化し、オーバーライドで振る舞いを置き換えます。
- 7:02子にだけ渡す情報にはプロテクテッド、実装を任せる共通の土台にはアブストラクト、
- 7:06という使い分けです。
- 7:09実行は、記事のファイルを保存し、ストリクトとノーインプリシットオーバーライドなどを付けたコマンドでコンパイルして、
- 7:14生成されたジャバスクリプトを実行します。
- 7:19節ごとにファイルは分け、例同士を一つに結合しないでください。
- 7:23練習として、新しい子クラスを一つ足す場合と、委譲で書く場合を比べてみると、
- 7:26判断の感覚がつかめます。
- 7:29継承は強力ですが、契約ごと引き継ぐ仕組みだという意識を忘れないでください。
- 7:34お疲れさまでした。
この動画で学べること
TypeScriptのクラスの継承を実行例で解説。extends・super・override・protected・抽象クラスの役割、親の契約、委譲との使い分けを学べます。
解説記事・サンプルコードを読む:TypeScriptのクラス継承:extends・super・abstractの使い方 →