プログラミング言語の観点では、サブタイピングとはどういう意味ですか?「継承はサブタイピングではない」と聞きました。それでは、継承とサブタイピングの違いは何ですか?
プログラミング言語の観点では、サブタイピングとはどういう意味ですか?「継承はサブタイピングではない」と聞きました。それでは、継承とサブタイピングの違いは何ですか?
回答:
[オブジェクト指向型システムの問題について深く考えたことはありませんが、議論を進めるために知っていることを述べます。]
タイプの構造は偶発的な理由で一致する可能性があるため、構造的なサブタイピングでは動作のサブタイピングが保証されません。ただし、予想される動作を定義するのは簡単ではありません。そのため、多くのプログラミング言語では、ユーザーがどの型がどのサブタイプであるかを宣言する必要がある中間点を使用します。これは、「名義サブタイピング」と呼ばれます。暗黙的サブタイプと明示的サブタイプに関する質問を参照してくださいこの問題の議論のため。アイデアは、プログラマーが自分の工夫を使用して、宣言されたすべてのサブタイプの動作サブタイプを確認する必要があるということです。この言語はヘルプを提供できません。ただし、宣言されたすべてのサブタイプは、少なくとも構造的なサブタイプでなければなりません。そうしないと、プログラムは型チェックに失敗します。言語はこれを保証するのに役立ちます。(一部のプログラミング言語には、コンパイル時にこれを保証するのに十分な型システムがありません。その場合、実行時に型障害が検出されるか、間違った結果が生成される可能性があります。
オブジェクト指向プログラムでサブクラスを定義するとき、一般に公開されているフィールド(またはメソッド)を追加します。ほとんどのプログラミング言語では、このようなサブクラスは名目上のサブタイプと見なされます。問題は、それらが構造サブタイプでもあるかどうかです。そうでない場合、つまりプログラミング言語で、構造サブタイプではない名目上のサブタイプを宣言できる場合、プログラミング言語にタイプホールが存在します。
単純な場合、フィールドの追加は正常に機能します。スーパークラスのタイプは、サブクラスのタイプよりも少ないフィールドを想定しています。そのため、sueprclassのインスタンスが予期されるサブクラスのインスタンスをプラグインすると、プログラムは提供された追加フィールドを無視し、何も問題が発生しません。
ただし、スーパークラスまたはサブクラスに、それ自体と同じ型の引数を取るメソッドがある場合、または同じ型の結果を返すメソッドがある場合、問題が発生します。その場合、サブクラスのインターフェイスタイプは、スーパークラスのインターフェイスタイプの構造的なサブタイプではありません。Javaなどの広く使用されているタイプセーフプログラミング言語では、このようなサブクラスは許可されません。そのため、型安全性を得るために言語を制限します。プログラミング言語Eiffelは、代わりに柔軟性を得るために型安全性を犠牲にしたと言われています。柔軟性を保持する強力な型システムを設計する場合、サブクラスがサブタイプを生成するという原則を放棄する必要があります。したがって、論文のタイトルは「継承はサブタイプではありません」。著者は、代わりに機能する高次サブタイピングの異なる概念を提案しています。キム・ブルースには、同じ効果を達成する「マッチング」と呼ばれる密接に関連した提案もあります。このプレゼンテーションを参照してください。Andrew Blackのポジションペーパーも役立ちます。
セマンティックスコミュニティは、おそらく問題をほとんど無視していることのせいです。私たちは伝統的に、理論的にほとんど関心のない実用的な型システム工学の問題だと考えてきました。それが当てはまらず、その分野で実際にいくつかのセマンティクスが機能している場合、他の人々がそれらに言及することを望みます。