思わずこんなタイトルをつけてしまったが、車ではなくてオブジェクト指向のお話。
車はガソリンがなければ動きません(ディーゼル他、非ガソリン車はとりあえず置いといて)。最近高いですね、ガソリン。
ご存知のように、ガソリンにはレギュラーと廃屋ハイオクがあります。
レギュラー用のエンジンにハイオクを入れても大丈夫ですが、ハイオク用のエンジンにレギュラーを入れると壊れてしまいます。
面倒なのでコードは載せません。各々補完してください。
車クラスとガソリンクラスがあります。
車クラスには、ガソリンのインスタンスを引数に取る給油メソッドがあります。
車クラスから、ハイオク専用車クラスを派生させます。
このハイオク専用車クラスの給油メソッドの引数は、多くの言語ではガソリンになりますが、実際にはガソリンから派生したハイオクガソリンを渡さないと壊れてしまいます。
I車インターフェイスではなく車クラスから派生させるのは、レギュラー用エンジンを積んでいる車には(悪質なものでない限り)どんなガソリンを入れても大丈夫だからです。この点において、レギュラー車はハイオク車より抽象的です。
ハイオク専用車も車の一種には違いなく、ハイオクガソリンもガソリンの一種には違いないのに、車とガソリンに結合が関係があるとき、これらを継承関係にするとうまく行きません。
よくある「ペンギンは鳥か?」論によれば、いくつかの結論のパターンがあります。
たとえば、
- 現実世界がどうであれ、このプログラム中では、どんなガソリンでも給油できるものを車と定義したのだから、ハイオク専用車はその意味では車ではなく、車クラスから派生させることは不適当である
- ハイオク専用車の給油メソッドでは、実際に給油されたガソリンの動的な型を判別して、ハイオクガソリンでなければ例外を投げればよい。
というような。
1は、「ペンギンは鳥か?」論でもそうですが、常識的に考えて「そんな馬鹿な」と言いたくなります。
まして、ペンギンと鳥は実際にも姿形も生態も大きく異なるのに対し、今回の例では、より違いが少ないだけになおさらです。
2は現実的な解かもしれません。しかし、極論を言ってしまえば、型のエラーをコンパイル時に検出できないなんて、静的型システムに何の意味があるというのでしょうか?
もちろん、完璧主義に走るべきではなく、完全に検出できないからと言って全く役に立たないわけではないという意見は一理あります。
しかし、完璧を求めてうまく行く方法があるとしたら、それを求めないのは罪というものです。
さて、お題です。
このような状況下でも、静的な型チェックを機能させる方法はあるのでしょうか?
- こういう仕様の新しい言語を作ればうまく解決できる
- 既存の言語にこういう拡張を施せばうまく解決できる
- 実は拡張しなくても既存の言語でうまく解決できる
- そもそも問題設定に無理があって、どうやっても解決は無理、または不要
- だから動的言語を使えっつってんだろ
- 他
既成概念に囚われない答えを募集します。