TypeScriptのClass,継承

2019/03/26

TypeScriptでのClass宣言

name,ageプロパティ、showメソッドがあるPersonクラスを定義

//Class宣言
class Person {
  //プロパティ
  name: string;
  age: number;
  //コンストラクター
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
  //メソッド
  show():string {
    return `${this.name}は${this.age}歳です。`
  }
}

//作ったClassを使用
const person = new Person('太郎', 15); 
console.log(person.show()); //太郎は15歳です。

アクセス修飾子

先ほどのコードでは、クラスの外からでもクラスのメンバーにアクセスできてしまいます。

const person = new Person('太郎', 15); 
console.log(person.name) //太郎

プロパティ、メソッドにアクセス制限をつけるのがアクセス修飾子です。

  • 「public」 クラスの外からでも自由にアクセスできる(デフォルト)
  • 「protected」 同じクラス、またはその派生クラス
  • 「private」 同じクラスからのみアクセス可能

先ほどのPersonクラスをアクセス修飾子を使って修正
name,ageプロパティをクラス外からのアクセスを制限

class Person {
  //private修飾子を使用
  private name: string;
  private age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
  show():string {
    return `${this.name}は${this.age}歳です。`
  }
}

const person = new Person('太郎', 15);
console.log(person.show()); //太郎は15歳です。
console.log(person.name); //エラー

private修飾子を使用したことで、showはクラス内メソッドなのでname,ageにアクセスできますが、
クラス外からはアクセスできないためperson.nameはエラーになります。

コンストラクターとプロパティ設定

this.プロパティ名 = 引数で与えられた引数を元にプロパティを初期化しています。
引数name,ageを元に同名のname,ageプロパティをコンストラクターで初期化

class Person {
  private name: string;
  private age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

これをTypeScriptではシンプルに書くことができます。

class Person {
  constructor(private name:string,private age:number){}
}

これでname,ageプロパティを生成、初期化ができます。
コンストラクターの引数にアクセス修飾子を付与します。これはpublicの場合でも省略することはできません。

継承

クラスを継承するにはextendsで元となるクラスを示します。
一度に一つのクラスしか継承できません。
継承元となるクラスをスーパークラス、親クラス、基底クラス等と呼ぶ。
継承してできたクラスをサブクラス、子クラス、派生クラス等と呼ぶ。

name,ageのアクセス修飾子をprotectedとしているのは派生クラスでもアクセスできるようにするためです。
privateだと派生クラスからアクセスできない

下記のコードではPersonクラスを継承してhobbyPersonクラスを定義しています。
hobbyPersonクラスではPersonクラスのshowメソッドに加えて、hobbyメソッドを使用することができます。

class Person {
  constructor(protected name:string,protected age:number){}
  show():string {
    return `${this.name}は${this.age}歳です。`
  }
}

class hobbyPerson extends Person {
  hobby():string {
    return `名前は${this.name}です。趣味がいっぱい。`;
  }
}

const person2 = new hobbyPerson('太郎', 15);
console.log(person2.hobby()); //太郎は15歳です。趣味がいっぱい。
console.log(person2.show()); //太郎は15歳です。

メソッドのオーバーライド

基底クラスで定義済みのメソッド、コンストラクターを派生クラスで上書きすることをオーバーライドと言います。

基底クラスで定義済みのshowメソッド、コンストラクターを派生クラスでオーバーライド

class Person {
  constructor(protected name:string,protected age:number){}
  show():string {
    return `${this.name}は${this.age}歳です。`
  }
}

class hobbyPerson extends Person {
   // コンストラクターをオーバーライド
  constructor(name:string,age:number,private hobby:string){
    super(name,age)
  }
  // showメソッドをオーバーライド
  show():string {
    return super.show() + `趣味は${this.hobby}です。`;
  }
}

const person2 = new hobbyPerson('太郎', 15, 'JavaScript');
console.log(person2.show()); //太郎は15歳です。趣味はJavaScriptです。

superで基底クラスのコンストラクター、メソッドを呼びだすことができます。
新しくhobbyプロパティを定義して、name,ageはsuperで基底クラスのプロパティを呼び出しています。
showメソッドではsuper.show()で基底クラスのshowメソッドを呼び出して、それに加えて、hobbyを表示するようにしています。