海未「最終回はジェネリクスです。日本語では総称型と言うこともあるようですがあまり馴染みはないですね」
穂乃果「・・・」
海未「穂乃果?」
穂乃果「・・・ファイナルのチケット・・・」
ことり「まだLVがあるよ穂乃果ちゃん!」
海未(私たちは出演者のはずでは・・・)
海未「クラスの中で使用する変数や関数の型を、クラスを定義する時点では決定せず後から指定することができます。これを利用すると以下のようなコードが書けます」
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
class Unit<T> { private members: T[] constructor() { this.members = []; } get(index: number) { return this.members[index]; } add(member: T) { this.members.push(member); } } class SchoolIdol { constructor( name: string, age: number, school: string ) {} sing() { console.log('Singing!!'); } dance() { console.log('Dancing!!'); } } class ProfessionalIdol { constructor( name: string, age: number, production: string ) {} sing() { console.log('Singing!!'); } talk() { console.log('Talking!!'); } } var honoka = new SchoolIdol('Honoka Kosaka', 16, 'Otonokizaka High'); var kotori = new SchoolIdol('Kotori Minami', 16, 'Otonokizaka High'); var hanayo = new SchoolIdol('Hanayo Koizumi', 15, 'Otonokizaka High'); var uzuki = new ProfessionalIdol('Uziki Shimamura', 17, '346Pro'); var rin = new ProfessionalIdol('Rin Shibuya', 15, '346Pro'); var mio = new ProfessionalIdol('Mio Honda', 15, '346Pro'); var printemps = new Unit<SchoolIdol>(); printemps.add(honoka); printemps.add(kotori); printemps.add(hanayo); var newGenerations = new Unit<ProfessionalIdol>(); newGenerations.add(uzuki); newGenerations.add(rin); newGenerations.add(mio); newGenerations.add(honoka); // error |
海未「おなじみのSchoolIdolとProfessionalIdolですが、イベントに向けてそれぞれユニットを組ませることにしましょう」
穂乃果「前回は配列に入れてなかったっけ?」
海未「とりあえずは配列でもいいのですが、ユニットの機能を今後増やしていくことを考えるとクラスになっていた方が好ましいですね」
ことり「ユニットには名前があったり、持ち曲とか出演履歴とかが管理できてもいいかも」
海未「今回のコードのUnitクラスは配列にgetterとsetterを付けた程度ですが、ジェネリクスの最低限の説明には十分でしょう」
海未「さて、Unitクラスから見ていきましょう。Unit<T>
と宣言していますが、このTは型を表す変数だと考えてください」
穂乃果「うーん・・・」
海未「membersはT型の配列、addメソッドの引数はT型、といったふうに定義されているのは分かると思いますが、このTは後からいろいろ変わり得るのです」
海未「コードの下の方で、Printempsやニュージェネのインスタンスを作っているところが鍵です。new Unit<SchoolIdol>()
のようにインスタンスを作っていますね」
ことり「このSchoolIdolがTになるのかな?」
海未「そうです。ですから、var printemps = new Unit<SchoolIdol>()
とした場合、Unitクラスは」
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class Unit { private members: SchoolIdol[] constructor() { this.members = []; } get(index: number) { return this.members[index]; } add(member: SchoolIdol) { this.members.push(member); } } |
海未「このように定義されているものとして振る舞いますし、var newGenerations = new Unit<ProfessionalIdol>()
であれば」
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class Unit { private members: ProfessionalIdol[] constructor() { this.members = []; } get(index: number) { return this.members[index]; } add(member: ProfessionalIdol) { this.members.push(member); } } |
海未「こう定義されているものとして振る舞います」
ことり「<>
の中に書いた型でTが置き換わるんだ」
穂乃果「スクールアイドルのユニットとか、本業のアイドルのユニットとか、アルパカの集団とか、1つのUnitクラスでいろんなバリエーションが作れるんだねっ!」
海未「SchoolIdolUnitとかProfessionalIdolUnitのように扱う型ごとにクラスを増やす必要がなくなるのが大きなメリットですね」
海未「ではTypeScriptに関してはこんなところで。まだ紹介していない言語機能もあるのですが、普段使いそうな機能は網羅できていると思います」
ことり「次はどうするの?」
海未「全くの未定ですね・・・さすがに講師役も疲れてきたところではありますが」
ことり「アルパカさんと学ぶPerl入門・・・」
穂乃果「何その狂気を感じる連載っ!?」
海未「まあ、今考える話でもないでしょう。一旦、この連載はおしまいです」
穂乃果「それじゃ、今回もお相手は高坂穂乃果とっ!」
ことり「南ことりと♪」
海未「園田海未でした♡」
3人「「「まったねーっ!!」」」