friend
クラスが定義されているパッケージの外部から使用できるメソッドとインスタンス変数をより細かく制御できるようにするために、C++ で使用できるディレクティブを使用せずに Java が設計されているのはなぜだろうと思っていました。
実用的な理由や特定の欠点は見当たりません。これは単なる設計上の問題のようですが、言語に追加しても問題は発生しないようです。
friend
クラスが定義されているパッケージの外部から使用できるメソッドとインスタンス変数をより細かく制御できるようにするために、C++ で使用できるディレクティブを使用せずに Java が設計されているのはなぜだろうと思っていました。
実用的な理由や特定の欠点は見当たりません。これは単なる設計上の問題のようですが、言語に追加しても問題は発生しないようです。
一般的に、認知の複雑さが増し、改善をもたらすケースが少ないためだと思います。
現時点で本番環境にあるJavaの非常に膨大な数の行は、friend
キーワードが実際には大きな損失ではないことを証明できると思います:)。
より具体的な理由については、@dwb の回答を参照してください。
ここに私の頭の上のいくつかの理由があります:
非常に素朴で経験の浅いプログラマだけが、友人に反対するだろう. もちろん、それは悪用される可能性がありますが、公開データも悪用される可能性がありますが、その機能は提供されています。
一般的な意見とは反対に、特にインフラストラクチャ機能の場合、フレンド アクセスが悪い設計ではなく、より良い設計につながる多くのケースがここにあります。メソッドを強制的に公開する必要がある場合、カプセル化に違反することがよくありますが、Java はフレンドをサポートしていないため、選択の余地はありません。
前述のパッケージの可視性に加えて、Java は、デフォルトでフレンドであるだけでなく、含まれるクラスへの参照も自動的に持つ内部および匿名クラスも提供します。そのようなヘルパー クラスを作成することはおそらくfriend
C++ で使用する唯一の合理的な方法であるため、Java にはそのための別のメカニズムがあるため、それは必要ありません。イテレータは、この非常に良い例です。
他の回答に追加するだけです:
Java にはデフォルトのパッケージ可視性があります。したがって、同じパッケージ ネイバー内のすべてのクラスを呼び出すことができます。その場合、隣人に表示するものを明示的に制御できます-パッケージの可視性を持つメンバーだけです。
つまり、本当の友達ではありませんが、似ている可能性があります。そして、はい、これも悪い設計につながります...
Java ではフレンド クラスを同じ場所に配置する必要があると単純に考えてみませんか? パッケージ プライベートの可視性により、同じパッケージの全員がそれらのメンバーにアクセスできます。したがって、明示的に宣言された友達に限定されるだけでなく、(既存または将来の) 友達が、この目的のために特別に設計された一部のメンバーを変更することを許可します (ただし、あなたのプライベートなものは変更しません)。カプセル化に完全に依存することができます。
私の意見では、ある種のフレンド機能 (必ずしも C++ のものと非常に似ているわけではありません) は、Java のいくつかの状況で非常に役立ちます。現在、パッケージのプライベート/デフォルト アクセス ハックを使用して、同じパッケージ (String
およびStringBuffer
たとえば) 内の密結合クラス間のコラボレーションを可能にしていますが、これにより、プライベート実装インターフェイスがパッケージ全体に開かれます。パッケージ間には、さまざまな問題を引き起こす邪悪なリフレクション ハックがあります。
Java でこれを行うには、さらに複雑な点があります。C++ は、関数のオーバーロード (および類似のもの) を解決する間、アクセス制限を無視します - プログラムがコンパイルされた場合、#define private public
何もすべきではありません。Java は (ほとんどの場合) アクセスできないメンバーを破棄します。友情を考慮に入れる必要がある場合、解決策はより複雑であまり明白ではありません。