なぜJavaで友達指令が欠けているのですか?
-
09-10-2019 - |
質問
なぜJavaがデザインされていないのか疑問に思っていました friend
C ++で利用可能な指令は、クラスが定義されているパッケージの外部から利用可能な方法とインスタンス変数をより細かく制御できるようにします。
私は実際的な理由や具体的な欠点を見ていません。それは単なるデザインの問題のように思えますが、言語に追加されても問題は発生しません。
解決
ここに私の頭の上のいくつかの理由があります:
- 友達は必要ありません。便利ですが、必須ではありません
- 友人は悪いデザインをサポートしています。あるクラスが友人への別のクラスへのアクセスを必要とする場合、あなたはそれを間違っています。 (上記を参照してください、便利で、必要ありません)。
- 友人はカプセル化を破ります。基本的に、私のすべてのプライベートは私のものであり、あそこのその男(私の友人)です。
他のヒント
一般に、それは認知的複雑さが追加され、それが改善をもたらす症例の数が少ないためだと思います。
私は、現時点で生産中の非常に膨大な数のJavaのラインが、 friend
キーワードは本当に大きな損失ではありません:)。
いくつかの具体的な理由については、 @DWBの回答をご覧ください。
非常に素朴で経験の浅いプログラマーだけが、友人に対して擁護します。もちろん、それは誤用される可能性がありますが、パブリックデータも同様ですが、その機能は提供されます。
一般的な意見とは反対に、特にインフラストラクチャ機能については、多くの場合があります。友人のアクセスは、より悪いデザインではなく、より良いデザインにつながります。カプセル化は、方法が実際にあるべきではないときに公開されることを余儀なくされたときに違反されることがよくありますが、Javaは友人をサポートしていないため、選択肢はありません。
前述のパッケージの可視性に加えて、Javaは、デフォルトで友人だけでなく、含まれるクラスへの参照も自動的に匿名のクラスを提供します。そのようなヘルパークラスを作成することがおそらく使用する唯一の合理的な方法であるため friend
C ++では、Javaには別のメカニズムがあるため、Javaは必要ありません。反復因子は、この非常に良い例です。
Javaが友人のクラスを共同で必要としていると単純に考えてみませんか?パッケージプライベートの可視性により、同じパッケージの全員がそれらのメンバーにアクセスすることができます。したがって、あなたは明示的に宣言された友人に限定されるだけでなく、(既存または将来の)友人が、この目的のために特別に設計された一部のメンバーを変更することを許可します(ただし、個人的なものではありません)。あなたはまだカプセル化に完全に依存することができます。
他の答えに追加するだけです:
デフォルトがあります パッケージの可視性 Javaで。だから、あなた たぶん......だろう 同じパッケージの隣人のすべてのクラスを呼び出します。その場合、隣人に見せるものを明示的に制御できます - パッケージの可視性を持つメンバーだけです。
だから、それは本当に友達ではありませんが、似ている可能性があります。そして、はい、これも悪いデザインにつながります...
私の意見では、Javaの状況によっては、ある種の友人機能(必ずしもC ++のものと非常に似ているわけではありません)が非常に役立つでしょう。現在、パッケージ/デフォルトのアクセスハックがあり、同じパッケージ内の厳密に結合されたクラス間のコラボレーションを可能にします(String
と StringBuffer
たとえば)が、これにより、パッケージ全体にプライベート実装インターフェイスが開きます。パッケージの間に、邪悪な反射ハックがあり、多くの問題を引き起こします。
Javaでは、これを行う追加の合併症が少しあります。 C ++は、機能の過負荷を解決しながらアクセス制限を無視します(および同様) - プログラムがコンパイルされた場合 #define private public
何もすべきではありません。 Javaは(ほとんど)アクセス不可能なメンバーを破棄します。友情を考慮する必要がある場合、解決はより複雑で、それほど明白ではありません。
SpaceGhostの声明に完全に同意します 彼の答え
一般的な意見とは反対に、特にインフラストラクチャ機能については、多くの場合があります。友人のアクセスは、より悪いデザインではなく、より良いデザインにつながります。
私の例は簡単です - クラスAがJavaのクラスBに特別な「友人」インターフェイスを提供する必要がある場合、同じパッケージにそれらを配置する必要があります。例外なし。その場合、AがBの友人であり、BがCの友人である場合、Aは常に真実ではないCの友人でなければなりません。この「友情の交換」は、C ++の友情がつながる可能性のある問題よりも、カプセル化を破ります。