私は Mason の説明に満足できなかったので、少し調べてみました。
言語設計者がコンストラクターの継承を省略することを選択する主な理由が 2 つあることがわかりました。
最初の理由はバージョン管理です。新しいコンストラクターが基本クラスに導入された場合、または基本クラスでコンストラクターの署名が変更された場合、サブクラスはそれらの変更を継承し、予期しない副作用につながる可能性があります。
この問題は、多くの場合、さまざまなタイプのフレームワークで表面化します。多くの場合、フレームワークの API の一部は、拡張することが期待されるクラス、または実装する抽象クラスで構成されています。フレームワーク クラスでコンストラクターの署名が変更された場合、これらの変更を継承しますが、ほとんどの場合、意味がありません。これは、「壊れやすい基本クラス」の問題として知られています。
2 番目の理由は、より哲学的な側面にあり、1 番目の理由と密接に関連しています。コンストラクターは、インスタンスを構築するときに、そのクラスのコンシューマーとして、クラスが必要とするものを定義します。つまり、クラス自体のニーズに関するものです。これを、クラスの実際の動作を定義するメソッドと比較してください。それは、クラスが何をするかについてです。それに基づいて、哲学的な議論は、継承は行動に関するものであり、ニーズに関するものではないということです。
これら 2 つの引数は、実際には同じコインの 2 つの側面です: ほぼ間違いなく、コンストラクターはクラスのニーズを定義するため、コンストラクターの継承は脆弱です。たとえば、基本クラスの作成者がすべてのニーズを予測できると期待するのは合理的ではありません。あなたの拡張クラスの。
または、少なくともその仮定を行うと (一部の言語が行うように)、基本クラスの有用性が大幅に制限されます。これは、拡張クラスに新しい動作を導入することしかできず、新しいニーズがまったくないためです。
私が思いついたもう 1 つのことは、完全性の問題です。これは個人的な好みの問題ですが、コンストラクターを継承する言語では、すべてのコンストラクターを学習して理解するには、基本クラスを何度も掘り下げる必要があることがよくあります。特定のクラスのインスタンスが構築されるさまざまな方法。
コンストラクターを継承できない場合、クラスの作成者は、クラスのインスタンスが構築されると予想されるすべての方法について明示する必要があります - これらのコンストラクターのいくつかが完全に自明なものになる場合でも、それらがクラス自体で定義されていることは、そのクラスの作成者がそれらを有用と見なし、別の作成者によって作成された可能性がある基本クラスのすべてのニーズを理解し、考慮する必要があることを示しています。
基本クラスのニーズが拡張クラスのニーズと一致するかどうかについて積極的に検討することなく、基本クラスのニーズをやみくもに継承するのではなく。
実際には、ニーズが一致していないことがわかりました。しかし、それらが整列したとしても、それらがどのように整列するかを考えることを強いられることは、より高いコード品質につながります。言語設計者がコンストラクターの非継承を選択するのは、それが哲学であると私は信じています。そこに書かれるコードとして。