#書きたい記事はいっぱいあるんだけど、重いやつは後回し…w
オブジェクト指向の三本柱は「カプセル化」「継承」「多態性」だと言われる。
最近、この「多態性」ってやつがよくわからなくなってきた。
一般的な説明は、「同じメソッドでもクラスが違えば挙動が違う」というやつだ。
よく使われる例だが、平面図形を表すShapeクラスを作り、この図形を描画するDrawメソッドを持たせたとしよう。
Shapeは抽象クラスなので、Drawは派生クラスであるRectangleとかCircleとかTriangleといったクラスによって実装される。
ここで、「同じDrawメソッドでも、RectangleとCircleでは違う挙動を示す」ことが「多態性」だと言われる。
これをめぐって、脳内で甲と乙が言い合いをしている。
- 甲:
- Rectangleクラスは、メンバとして縦の長さと横の長さを持っている。それらの値が違えば、描かれる図形は当然異なる。
一方のインスタンスは1cm×1cmの正方形を描き、もう一方のインスタンスは3cm×5cmの長方形を描いたとき、これは「同じDrawメソッドでも挙動が異なる」ことにはならないのだろうか。
- 乙:
- Rectangleクラスは「長方形」でしかない以上、Drawメソッドの効果は「長方形を描く」ということだけだ。描かれた結果を抽象してみれば、どちらも長方形を描いていることに変わりはないのだから、同じ挙動であると言える。
- 甲:
- なるほど、Rectangle.Drawの意味は確かに「長方形を描く」であるかもしれない。だとすれば、Circle.Drawは「円を描く」であり、Triangle.Drawは「三角形を描く」だ。
ところで、多態性とは「同じメソッドであっても、クラスが違えば挙動が違う」であった。しかし、クラスが違えばメソッドの意味が違ってくることは今見たとおりだ。
さて、Rectangle.DrawとCircle.Drawは何を以てして「同じメソッドである」と言えるのだろうか。
- 乙:
- 多態性と継承は切っても切れない関係にある。
確かに、Rectangle.DrawとCircle.Drawの意味は違う。しかし、
Shape s = new Rectangle();
s.Draw();
と
Shape s = new Circle();
s.Draw();
では、呼び出しているのはどちらもShape.Drawでありながら、その結果が異なる。
「派生型は基底型を通じて参照できる」という原則のもとでは、「同じメソッド」と言えるだろう。
- 甲:
- 先程、Rectangle.Drawは単に「長方形を描く」メソッドに過ぎないのだから、実際に描かれた図形が、どうであれ長方形である以上、その大きさは問題にならないとした。
その理屈を適用すれば、Shape.Drawの意味は「平面図形を描く」ということだけだ。ということは、結果として描かれたものが長方形であれ円であれ、「違う挙動」とは言えないのではないだろうか。
- 乙:
- 同じShape.Drawを呼び出していながら、RectangleとCircleでは実行されるコードが異なるのだから「違う挙動」である。
- 甲:
- では、Rectangle.Drawのコードが以下のようになっていたとしたらどうか。
if( 縦の長さ == 横の長さ )
{
正方形を描く();
}
else
{
長方形を描く();
}
これでも、1cm×1cmの場合と3cm×5cmの場合とで「同じコードが実行されている」と言えるか?
- 乙:
- その通り。途中で分岐していようが、全体としてRectangle.Drawが実行されているのだから、どちらのケースも単一のRectangle.Drawである。
- 甲:
- なるほど。メソッドの入口と出口さえ共通であればよいと。
では、Shape.Drawが実行される様子を想像しよう。
- クライアントがShape.Drawを呼ぶ
- Shape.DrawはRectangle.Drawを呼ぶ
- Rectangle.Drawが終わったら、呼び出し元のShape.Drawに戻る
- Shape.Drawからクライアントに制御が返る
このような実装方式になっていた場合、中身がRectangleだろうがCircleだろうが、入口と出口はともにShape.Drawで共通である。
全体としてShape.Drawが実行されているのだから、「違う挙動」とは言い難い。
それとも、このように実装されたものは多態性と呼ばないとでも言うか?
- 乙:
- 実際に描画しているコードが異なるのだから違う挙動である。
- 甲:
- 先程言ったことと矛盾している。
実際に描画するロジックが何であれ、総体としてRectangle.DrawならばRectangle.Drawであると言ったばかりではないか。
なんだか甲が有利だ。
当議論は、あなたの乱入をお待ちしております!