Abstract修飾子
Abstractとは「抽象的な」という意味。
Abstract修飾子はアクセス修飾子とは違い、メンバ変数、メンバ関数以外にも、クラスそのものにつけることができる。
Abstract修飾子をクラスにつけた場合、そのクラスを抽象クラスと呼ぶ。メンバにつけた場合も抽象メンバと呼ばれる。
抽象クラスは以下の特徴がある。
- 抽象クラスは直接インスタンス化することができない。抽象クラスを継承したクラス(子クラス)を作る必要がある。
- 抽象メンバは直接アクセスできない。子クラスで具体的な処理を実装する必要がある。
試してみましょう。
type Temperture = 'hot' | 'cold';
abstract class Drink {
name: string = 'hoge';
private capacityMl: number = 500;
protected price: number = 600;
static num: number = 0;
constructor(public temperature: Temperture) {
Drink.num++;
// console.log('Drink:', this.name);
// console.log('Drink:', this.capacityMl);
// console.log('Drink:', this.price);
}
abstract getTaxIncludedPrice(): number;
}
class Tea extends Drink {
constructor(public temperature: Temperture, public brand: string) {
super(temperature);
// console.log('Tea:', this.name);
// console.log('Tea:', this.capacityMl); // プロパティ 'capacityMl' はプライベートで、クラス 'Drink' 内でのみアクセスできます。ts(2341)
// console.log('Tea:', this.price);
}
getTaxIncludedPrice(): number {
return this.price * 1.1;
}
}
const drink1 = new Drink('hot'); //抽象クラスのインスタンスは作成できません。ts(2511)
const tea1 = new Tea('hot', 'assam');
console.log('tea1:', tea1.getTaxIncludedPrice()); // tea1: 660
前回作った飲み物クラスにabstractをつけて抽象クラスにしました。
そうすると、飲み物クラスはインスタンスが作成できなくなりました。
また、飲み物クラスに税込価格を返す抽象メンバ関数を作成しました。
そうすると、紅茶クラスで
非抽象クラス 'Tea' はクラス 'Drink' からの継承抽象メンバー 'getTaxIncludedPrice' を実装しません。ts(2515)
とエラーが出るようになりました。
子クラスである紅茶クラスで具体的な実装を書く必要があります。
紅茶クラスでgetTaxIncludedPriceを実装すると、飲み物クラスで定義していたpriceの600が660と計算されて返却されました。
使い道
抽象クラスは子クラスのドキュメントとなるような存在です。
予め定義を決めておくことで挙動や変数を統一し、処理の流れをわかりやすく、また可読性をあげることができます。
コメント