Part6:インターフェイスと構造的部分型

海未「それではインターフェイスの話を始めましょう」
穂乃果「あれ、意外と元気だ」
ことり「海未ちゃんね、だんだん責めても動じなくなってきて・・・」
穂乃果「あー、毎度のことで順応してきたんだ・・・」

海未「インターフェイスという概念は、JavaやC#を知っている人にとっては馴染みのあるものでしょう。実装を持たない型定義です」
穂乃果「実装を持たない・・・型定義・・・?」
海未「まず、このコードを見てください」

海未「似たようなコードは何度も出てきた気がしますが、クラスが3つ普通に定義されていますね」
ことり「アルパカさん10歳だったの?」
海未「・・・適当です。さて、ここでアイドルフェス的なものが開催されることになり、出演者を出演順に配列に入れていくとしましょう。ところが・・・」

海未「例えばこう書くと、コンパイルエラーになります。uzukiはSchoolIdolではないからですね」
ことり「じゃあ、var casts: ProfessionalIdol[] = [honoka, uzuki]もだめだよね」
穂乃果「だからってany[]にしちゃうと、フェスにアルパカが入り込んじゃうよね」
海未「そうです。この場合、以前見たようにSchoolIdolとProfessionalIdolが同じIdolクラスを継承している、といった構成になっていれば問題はないのですが、今回は別の方法をとりましょう」

海未「Singableというインターフェイスを用意して、SchoolIdolとProfessionalIdolはそれをimplementsすることにしましょう。こうすると、SchoolIdolとProfessionalIdolをどちらもSingable型として同じ扱いができるようになります」
穂乃果「歌える人だけ出場権があるんだ」
海未「Singableインターフェイスではsing(): voidという宣言がありますが、これはSingableインターフェイスを実装するクラスは必ずsingメソッドを持っていなくてはならないということです」
ことり「だからコードの最後で、キャスト全員のsingを呼び出したりできるんだね」

海未「この例では配列について見ましたが、同様に高階関数の引数宣言にも適用できます。また、クラスの継承関係に関係なく実装できますから、継承構造をまたがってグルーピングをしたい場合に便利ですね」

海未「最後に、これをインターフェイスなしに実現する方法を紹介します。構造的部分型という仕組みです」

海未「ProfessionalIdolにdanceメソッドを追加しました。これによって、ProfessionalIdolはSchoolIdolと同じsingとdanceの各メソッドを持っていることになります」
穂乃果「ふむふむ」
海未「そうすると、SchoolIdol型が要求されるところに代わりにProfessionalIdolを渡すことができるようになります」
ことり「たしかに、SchoolIdolの配列に卯月ちゃん入れてるけど・・・どうしてなのかな」
海未「ProfessionalIdolはSchoolIdolと同じことができるから、ですね。singもdanceもできますから外から見た振る舞いは同じですし、実際JavaScriptでは同じことができました」
穂乃果「ダックタイピングだね」
ことり「ちゅんちゅん」

海未「次回はジェネリクスを紹介します。それで、TypeScriptの主な機能は一通りですね」


LINEで送る
Pocket


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です