※ この投稿はオブジェクト指向 Advent Calendar 2014 - Qiita の12/25の記事です。
安倍晴明 オブジェクト指向について語ること##
「おい晴明、おれはまたわからなくなってしまったよ。オブジェクトとは一体何なのだ」
「オブジェクト指向のオブジェクトのことか」
「そうだ、そのオブジェクトだ。まあ、クラスの書き方はこうだ、それをインスタンス化するにはどうだということはなんとなくわかるのだが、そうやって書くことがどんな意味を持っているのか、おれにはさっぱり……」
「そうか、わからぬか。ならば答えよう。オブジェクトとはな、呪(しゅ)だ」
「ちょっと待て晴明、それはいくらなんでも乱暴だろう!? 」
「何が乱暴だ。時代設定を無視してオブジェクトとは何だなどと問うてきたのは博雅よ、お前のほうではないか」
「いやそれはそうなんだが……しかし、お前のいつもの『名とは呪だ』といい、何でもかんでも呪にしてしまうというのはどうなのだ」
「別に何でもかんでも呪にしているわけではない。おれは、これは呪だと思うものしか呪とは言わぬさ。そもそも、プログラミングにおいては適切な名づけこそが読みやすくバグの少ないコードにつながる。名が呪であるならば、オブジェクト指向に限らず、プログラミングという行為そのものが呪であるとすら言えるだろう」
「ううむ、そういわれるとそんな気もするような、うまく丸め込まれたような―――」
「ははは、まだ納得がゆかぬか。ではこういうのはどうだ。お前はいつぞや、朱雀門に現れた鬼と笛を合奏したと言っていたな」
「うむ、あれは不思議な夜であった。どこからともなく美しい調べが流れてきて、思わず自分の笛を合わせてしまったのだ。あの時はまさか、相手が人ならぬ存在であるとは夢にも思わなんだが―――」
「さて、そこよ。お前は人であり楽士である。だからこのように書ける」
public class Human
{
(略)
}
public class MusicPlayer : Human
{
public void Play(Instrument instrument)
{
(略)
}
}
public class Program
public static void Main(string[] args)
{
MusicPlayer Hiromasa = new MusicPlayer()
Hiromasa.Play(new Flute());
}
}
「なるほど、人を継承した楽士クラスを定義して、おれという楽士のインスタンスを生成するのだな」
「そうだ。他にも源脩どのや敦実親王など、楽を奏するものはみな楽士クラスのインスタンスとして生成できる。これで宮中の宴での合奏ができるな」
「うむ」
「ところが、そこへ鬼がふらりと現れて『おれも合奏に加えてくれ』と言ったとしよう。鬼は人と一緒に楽を奏することはできるだろうか? 」
「ううむ……いや、無理だろうな」
「そうだな、人はみなおびえて逃げ出すか、あわてて鬼を追い払ってしまうだろう。鬼は人ではない。だから人を継承した楽士にはなれぬというわけだ。だが、中にはおまえのように、相手が鬼であるか人であるかにはとんと執着せず、よい楽を奏でていれば自分も合わせて奏したいと思うような物好きもいる」
「いや、別に執着しないわけではないぞ。ただ知らなかっただけだ」
「まあそれはどちらでもよい。ともあれ、お前が鬼と笛を合わせたいと思うならば、楽士が人を継承したままであってはうまくいかぬ」
「ではどうするのだ」
「楽士は人を継承するのをやめてしまうのさ。そして、人と鬼とを『楽を奏するもの』という呪でくくる。これが、オブジェクト指向型の言語でよく用いられる、インタフェースだ」
public class HumanPlayer : IMusicPlayer
{
public void Play(Instrument instrument)
{
(略)
}
}
public class GoblinPlayer : IMusicPlayer
{
public void Play(Instrument instrument)
{
(略)
}
}
public interface IMusicPlayer
{
public void Play(Instrument instrument);
}
public class Program
{
public static void Main(string[] args)
{
IMusicPlayer Hiromasa = new HumanPlayer();
IMusicPlayer Oni = new GoblinPlayer();
List<IMusicPlayer> Players = new List<IMusicPlayer> { Hiromasa, Oni };
foreach(var player in Players)
{
player.Play(new Fluet());
}
}
}
「なるほど、人の楽士も鬼の楽士も、楽を奏するという同じメソッドを持っているから奏でる楽を合わせられるということか」
「そうだ。しかもおまえはさきほど自分で言ったように、相手が鬼であるか人であるか知らなくてよい。ただ楽を奏するこころを持っている、すなわち楽士インタフェースを実装していることさえ知っていれば、同じように合奏することができるのだ」
「ふむ、それは良いな」
「これはインタフェースだけではない。メソッドも、クラスも、オブジェクト指向における、名を持つものたちはみな同じ働きを持っているのさ」
「すべてか」
「うむ、すべてだ。ある時は目的に見合ったインスタンスを返すものにFactoryと名をつけ、またある時はある条件にかなっているかを調べることの頭にIsとつける。このように、曖昧模糊とした事物に名前をつけ、呪でくくることによってものごとがうまくまわるようにとりはからうことができる。これこそがオブジェクト指向プログラミングの目指すところであり、おれがオブジェクトとは呪であると述べる所以なのさ」
元ネタ
Amazon.co.jp: 陰陽師(おんみょうじ) (文春文庫): 夢枕 獏: 本
おまけ
私の勝手な解釈のつもりで書いておりましたが……
Schemeでは値に名前を付けることを束縛(bind)と呼んでいます。
プログラミングとは名前付け(bind)である - karetta.jp
おおう。bind=くくる、と考えると意外に的を射たかも。