Typescript(抽象クラス)
はじめに
前回記事の継承と関係のある抽象クラス(abstractクラス)についての記事を書きます。コードは前回、前々回の記事のものを使っていますので、コードの内容がよくわからないと感じる方はそちらの記事から読んでいただけると幸いです。
抽象クラスの使い方
//抽象クラス abstract class Person { constructor(protected readonly name: string, public age: number) {} abstract hello(): void; }
クラスの前にabstract修飾子がついています。この一行目からPersonクラスは抽象クラスだと判断できます。またhelloメソッドにもabstract修飾子がついています。これが意味するのは、Personクラスを継承したサブクラス(以下Japaneseクラス)はhelloメソッドを書くことを強制されます。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独自のプロパティを設定。 } }
JapaneseクラスではPersonクラスのhelloメソッドの型指定に沿ったhelloメソッドを記述する必要があります。
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"); } }
抽象メソッドには型レベルのコードしか受け付けません。
言葉の整理
・abstractが指定され、インスタンス化できない、継承元のクラスを抽象クラスという。(今回の例ではPersonクラス)
・抽象クラスを継承したサブクラスを具象クラスという。(今回の例ではJapaneseクラス)
・抽象クラスには実装しない(型の指定のみ行う)が、抽象クラスを継承した具象クラスには必ず実装しないといけないメソッドや値を抽象メンバという。(今回の例ではhelloメソッド)
↓矢印参考にした記事
numb86-tech.hatenablog.com