TypeScript~基礎編~クラス

こんにちは。KOUKIです。

本記事では、TypeScriptを使って、クラスの基本概念や活用方法について記事にしています。

クラスの使い方について詳しくなれると思いますので、ぜひご一読ください。

学習まとめ

環境構築

以下の記事で作成したプロジェクトを使います。
※TypeScriptが動けば問題ありません

クラスとは

クラス(Class)は、オブジェクトの論理上の設計図になります。オブジェクト構造(プロパティやメソッド)を定義し、同じ構造の似たオブジェクトを繰り返し作成することができます。

TypeScriptのクラスの実装

クラスを作成しましょう。

classキーワード

クラスを作成するためには、「class」キーワードを使います。

プロパティ

プロパティを定義する場合は、以下のようにします。

それぞれのプロパティに設定されているstringやnumberはTypeScriptの型です。

型については、以下の記事をご覧ください。

初期値を設定することも可能です。

KOUKI
KOUKI

しかし、通常は、コンストラクタを使うのが一般的ですね。

コンストラクタ

コンストラクタは、インスタンス化した時に最初に呼び出されるメソッドです。オブジェクトの初期化処理を行います。

インスタンス化

クラスを使えるようにするには、インスタンス化する必要があります。

クラスをインスタンス化するには、「new」キーワードを使います。

このインスタンス化により、selfnote変数にてクラスに対して操作を行うことができるようになります。

メソッドとthisキーワード

メソッドを定義する場合は、以下のようにします。

メソッドとして、自己紹介メソッド(speakMyself)を定義しました。

このメソッドの内部では、「this」キーワードを指定しています。このthisは、クラスから作成されたインスタンスを参照します。上記の例では、selfnoteを参照することになりますね。

private修飾子とpublic修飾子

JavaやC#を学んだことがある人にとっては馴染み深いかもしれませんが、TypeScriptにもアクセス修飾子(privateやpublic)があります。

private修飾子は、外部からの一切の干渉を拒絶します。

valuables(貴重品)をprivate修飾子付きで定義しました。これで、クラスの内部からでないとこのプロパティにはアクセスできません。

尚、アクセス修飾子は、メソッドにも定義可能です。

これが何が便利かというと、特定の操作方法を限定できたりします。

例えば、private修飾子を外して、valuablesプロパティを操作するメソッドを追加します。

本来であれば、addValuableメソッドの呼び出しで貴重品を追加したいところですが、プロパティの直接の呼び出しでも追加できてしまいます。

しかし、privateを設定した場合は、以下のようにエラーが発生します。

KOUKI
KOUKI

これは、結構便利です!

public修飾子はprivate修飾子とは逆で、クラスの外からアクセスすることが可能なアクセス修飾子です。アクセス修飾子をつけていないメソッドやプロパティはデフォルトでpublic修飾子がついた状態と同じになります。

プロパティ初期化のショートカット構文

コンストラクトを使うとプロパティの初期化の記述を短くすることができます。

readonlyプロパティ

アクセス修飾子と関連して、「readonly」プロパティという読み取り専用にする修飾子があります。

このように読み取り専用にしたいプロパティに対してreadonlyプロパティを設定すると値の書き換えが不可になります。もちろん、クラスの中からも変更できません。

KOUKI
KOUKI

これは読み取り専用だぞ」と開発者の意図を伝えるのに便利そうですね。

クラスの継承

クラスは、他のクラスに継承させることができます。継承とは、派生クラスを作成する機能です。

Japaneseクラスを継承したTokyoTominクラスを定義しましょう。継承するには、「extends」キーワードを使います。

上記のサンプルコードの通り、継承を行えば、継承元(Japanese)のプロパティやメソッドを引き継ぐことができます。それ故の派生クラスです。

派生クラスのコンストラクタ

派生クラスにコンストラクタを設定していない場合、インスタンス化時には継承元のコンストラクタが呼び出されます。

しかし、派生クラスにコンストラクタを設定すると派生クラスのコンストラクタが呼び出されます。その為、「super」キーワードを使って、継承元のコンストラクタを明示的に呼び出す必要があります。

protected修飾子

protected修飾子は、public修飾子やprivate修飾子と同じアクセス修飾子です。

これを使うと派生元のプロパティにアクセスすることができます。もちろんクラス外からはアクセスできません。

Getter & Setter

Getterは値を設定するメソッドで、Setterは値を設定するメソッドです。

これはTypeScriptの機能ではなく、モダンなJavaScriptでもサポートされています。

Getterを設定するには「get」キーワード、Setterを設定するには「set」キーワードをそれぞれ用います。

setterの使い方は少し混乱するかもしれません。

staticキーワード

プロパティやメソッドには、「static」キーワードを付けることができます。

staticキーワードを付与したプロパティやメソッドは、インスタンス化しなくてもアクセスできるようになります

abstractキーワード

クラスやメソッドに「abstract」キーワードを付けると、それらを抽象化することができます。

先ほどのBookクラスをabstractキーワードを使って抽象化します。

抽象化」とあるように、abstractをつけたメソッドには、具体的な処理内容を記述することができません。

これの何が便利だと言いますと、継承先のクラスにgetTitleを強制的にオーバーライドすることを義務付けることができます。

上記のコードでは、Bookを継承するHarryPotterクラスを定義しました。

しかし、以下のエラーメッセージが表示されます。

Class ‘HarryPotter’ incorrectly implements class ‘Book’. Did you mean to extend ‘Book’ and inherit its members as a subclass?
Property ‘getTitle’ is missing in type ‘HarryPotter’ but required in type ‘Book’.ts(2720)app.ts(44, 12): ‘getTitle’ is declared here.

このエラーを回避するために、HarryPotterクラスで、getTitleメソッドを定義します。

abstractは、絶対必須のメソッドを定義したいときに使用するのがいいと思います。また、継承先のメソッドごとに処理内容を変えることができるので、それも便利ですね。

KOUKI
KOUKI

ちなみにabstractをつけたクラスは、インスタンス化することができません

シングルトンパターン

最後にシングルトンパターンを学びましょう。

シングルトンは、「クラスのインスタンスが必ず一つであることを保証する」デザインパターンの一つです。

TypeScriptに関わらず、PythonやGo言語でも実装することができます。

TypeScriptでシングルトンを実装する場合は、privateのコンストラクタを定義する必要があります。

シングルトンは、プログラム実行中に複数のインスタンスが作成されることが望ましくない時に使用します。

例えば、DBにアクセスするインスタンスを作成する際、プログラム実行毎にDBにアクセスできるインスタンスが作られるのではなく、既にインスタンスが存在している場合は、それを経由してDBにアクセスする方が競合などを発生させずに、安心して利用できます。

まずは、DBManagerクラスを作成して、privateなコンストラクタを定義します。

privateでコンストラクタを定義すると、クラス外からインスタンス化ができなくなります。

続いて、インスタンス化するためのプロパティとメソッドを「static」キーワード付きで宣言します。

instanceプロパティは、クラス内からのみアクセスできるstaticなメソッドです。また、getInstanceもstaticキーワード付きで定義しました。

getInstanceを実装します。

インスタンスが存在しているかチェックして、存在している場合は、インスタンスをそのまま返却し、そうでない場合は、新規作成しています。

実際に同じインスタンスか確かめてみましょう。

取得したインスタンスを比較した結果、「true」が返却されたため、シングルトンの実装に成功したようです。

おわりに

TypeScriptのクラスの基本的な実装とその応用としてシングルトンパターンの実装を行いました。

覚えることが多くて大変ですが、実際に手を動かしながら実装すると、徐々に理解できるようになるはずです。

次は、TypeScriptのインターフェースを学びたいですね^^

それでは、また!

参考書籍