自分用のメモ。
- interface:オブジェクト、クラス、関数の型のみを宣言する
- type:どんな型でも宣言する
- extends:継承する
- implements:実装する
interfaceとtypeはすごく似てるので正直どちらを使っても良いっぽいです。
extends
例えば、冒険者(Adventurer
)というclass
があるとします。
class Adventurer{ name:string hp:number }
冒険者は名前とHPを持っています。
冒険者は別の職業にジョブチェンジできます。
ここでは冒険者→魔法使い(Wizard
)にジョブチェンジするものとするとして、Wizard
クラスを作るとすると以下のようになります。
//WizardクラスはAdventurerを継承しているのでhpとnameプロパティも持っている class Wizard extends Adventurer { mp: number }
このとき使うのがextends
。
extends
を使うと冒険者のプロパティをすべて継承する- つまり冒険者⊂魔法使いみたいな関係になる
new
演算子を使って、実体化(インタンス化)します。
//ハリーポッターを作る const HarryPotter = new Wizard();
interface
interface
は、オブジェクト・関数・クラスの構造を決めるためのもの。
要するに「このオブジェクトはこういう構造だぜ!」を決めるためのもの。
例えば、以下のような「空を飛べるよ!」なinterface
を作ります。
interface flyable { icanfly(): void }
このinterface
を実装されたクラスは空を飛べるようになります。
例えば、以下のようにWizard
クラスにflyable
を実装します。
class Wizard extends Adventurer implements flyable { mp: number icanfly(){ console.log("空を飛ぶよ!") } }
このようにinterface
を実装するには、implements
を使います。
ところで「構造を決めるためのもの」と言いつつ、関数を1つしか実装していないじゃないか!と思うかもですが、それは説明しやすくするためでございます。。
extends
extends
を使うとinterface
からinterface
へ継承できます。
例えば「瞬間移動できるよ!」なinterface
を作りたいとします。
ただし「瞬間移動」のスキルを身につけるには、「空を飛ぶ」スキルを先に身につけておかないといけないとしましょう。瞬間移動は空を飛ぶスキルの上位互換なのです。
そうすると、以下のように継承できます。
//空を飛べるよ!なinterface interface flyable { icanfly(): void; } //瞬間移動できるよ!なinterface interface teleportable extends flyable { icanteleport(): void; }
このとき、teleportable
なinterface
を実装されたWizard
クラスは、
- icanfly()
- icanteleport()
の両方のスキルを持つ必要があります。
class Wizard extends Adventurer implements teleportable { mp: number; icanfly() { console.log("空を飛ぶよ!"); } icanteleport() { console.log("瞬間移動するよ!"); } }
type
type
の正式名称は「Type Aliases」。
要するに「あだ名をつけるぜ!」な機能。
例えば、以下のような「空を飛べるぜ!」なtype
を作ります。
type flyable= { icanfly(): void }
このtype
を実装されたクラスは空を飛べるようになります。
例えば、以下のようにWizard
クラスにflyable
を実装します。
class Wizard extends Adventurer implements flyable { mp: number icanfly(){ console.log("空を飛ぶよ!") } }
interfaceとtypeの違い
「あれ?interface
と同じじゃね?」と思うかもですが、大体そのとおりです
ですが厳密にいうと
type
は宣言のときに=
が必要だけど、interface
は不要type
はextends
で継承できないが、交差型と呼ばれる機能で似たようなことができる- 同名の
type
を宣言するとエラーになるが、同名のinterface
を宣言するとマージされる type
はプリミティブ、配列、タプルなども宣言可能だけど、interface
はオブジェクトと関数のみ宣言可能
という感じで色々違うみたいです。このページでは詳しく説明しないので別のサイトでお調べください。
implements
例えば、冒険者というジョブを持つ人が存在しない場合、冒険者はinterface
やtype
として作っておき、「魔法使いなどの他の職業は冒険者を実装する」みたいな形にもできます。
interface Adventurer { name: string; hp: number; } class Wizard implements Adventurer { name: string; hp: number; mp: number; }
まとめ
class
にimplements
できるのは・・・
→class
、type
、interface
class
にextends
できるのは・・・
→class
のみ
type
にimplements
できるのは・・・
→class
、type
、interface
type
にextends
できるのは・・・
→なし
interface
にimplements
できるのは・・・
→class
、type
、interface
interface
にextends
できるのは・・・
→interface
、type
「typeをinterfaceにextendsできる」というのが個人的なハマりポイントでした。
おわり
コメント