14

就職の面接に参加しました。インタビュアーは、なぜプライベート変数が必要なのかと私に尋ねました。変数privateを定義して何かを達成する場合、Javaで定義されている他のアクセス修飾子を定義して同じことを達成することはできませんか?

Java仕様言語によると、

プライベートクラスのメンバーまたはコンストラクターは、本体内でのみアクセスできます。
メンバーまたはコンストラクターの宣言を囲む最上位クラス(7.6)。
サブクラスには継承されません。

しかし、クラスを設計している場合、変数「プライベート」を定義する決定をどのように行うことができますか?

4

9 に答える 9

39

「他のコード」(おそらく他の人によって書かれた/維持されている)へのアクセスを制限することにより、それに依存する他のコードを壊すことを心配することなく、将来それをより自由に変更できます。

問題は「これを非公開にするべきか」ではなく、「これを非公開にする必要があるか」ということです。変数へのアクセスが必要になる可能性が高い他のコードはありますか?

その場合は、適切なアクセスを割り当て(おそらくゲッター/セッターを介して)、変更が困難になることを受け入れます。それ以外の場合は、非公開のままにします。

于 2010-11-24T12:23:04.957 に答える
11

私はあなたがそれを別の方向から見るべきだと思います:なぜあなたは変数をプライベート以外のものにするのですか?適切なカプセル化とは、実装の詳細を非表示にすることを意味するため、デフォルトではフィールドをプライベートにする必要があります。

于 2010-11-24T12:23:58.517 に答える
8

基本的に、 variable を作成すると、publicコミットされ、この決定に戻ることはできなくなります。今後のすべての変更により、クラスのパブリック インターフェイスが変更されます。つまり、そのクラスのすべての使用法を変更する必要があります。パブリック API の場合、これは考えられません。あなたのライブラリは事実上下位互換性を壊しました。

私的に使用されるクラスであっても、これは大したことではありません。

では、変数のスコープをprivate将来いつ変更するのでしょうか? これには多くの考えられる理由があります。最も簡単な方法は、変数の値が変更されるたびにクラスで何かを行う必要がある場合です (変更をログに記録するか、それに応じて他の変数を更新するなど)。または、変数がまったく必要ないこと、およびユーザーが要求した値をその場で計算する必要があることを後で決定します。

変数を直接読み取ったり設定したりする場合、それは不可能です。代わりに、変数への直接アクセスを禁止し、代わりに適切な public getter/setter メソッドを提供することで、クラスはユーザーに getter/setter を呼び出すよう強制する必要があります。

一般に、このような将来の変化を予測することはできないため、変数を作成しないpublicことがベスト プラクティスとして受け入れられるようになりました。すべての変数private(または少なくとも内部) である必要があります。

(例外が 1 つあります。場合によっては、final変数を安全に作成できpublicます。たとえば、enum のような定数はpublic finalJava ライブラリで変数として実装されることがよくあります。これらの定数は決して変更されないためであり、とにかく読み取り専用であるためアクセス制御は必要ありません)。 .

于 2010-11-24T13:43:01.290 に答える
7

一般的な経験則は、変数とメソッドの範囲を縮小することです。プライベートに保つものが多ければ多いほど、システムの他の部分で問題を引き起こすことなくクラスを簡単に変更できます(つまり、カップリングを減らします)。

したがって、原則として、privateをデフォルトにする必要があります

于 2010-11-24T12:23:29.760 に答える
3

ですから、なぜ非公開にする必要があるのか​​を自問する必要があります。では、真理を矛盾観念で使ってみてはどうでしょうか。

公開できますか? 答えが、人々が属性に直接アクセスして変更できるようにしたくない場合は、パブリックにすることはできません。

デフォルトでいいの? 答えが、同じパッケージが属性に直接アクセスして変更できるようにしたくない場合は、デフォルトにすることはできません。

保護できますか 答えが、サブクラスが属性に直接アクセスして変更することを望まない場合、保護することはできません。

したがって、すべての答えが No である場合 (そして、これらのシナリオでアクセスを望まない理由の答えを決定する必要があります)、それはプライベートである必要があります。

問題は、モディファイアーがあなたに与えるものと、モディファイアーにアクセスする方法を本当に理解しているか、そして盲目的にすべてを非公開にし、セッターとゲッターを作成しないことです。

于 2010-11-24T12:25:46.270 に答える
3

変数 private を定義することで何かを達成する場合、Java で定義されている他のアクセス修飾子を定義することで同じことを達成することはできませんか?

はい。それは本当だ。Anyprivatepublic(などprotectedに) 変更すると、プログラムは以前と同じようにコンパイルおよび実行されます。

アクセス修飾子はプログラマーの便宜のためにあり、クラスのインターフェースを適切に定義するのに役立ちます。カプセル化に関するウィキペディアの記事をご覧ください。

于 2010-11-24T12:25:52.570 に答える
2

次の場合、メンバーは非公開です。

  1. これはプロパティであり、読み取りと書き込みはクラス メソッドを介してのみ実行する必要があります
  2. オブジェクトのコンテキストでのみ意味があり、それ以外の場所では意味がありません
  3. クラス外から見えないようにする

このような設計の目的はカプセル化です。つまり、クラスの実装がクライアント コードから隠されます。コードの可読性、保守性、およびテスト容易性が向上します。

于 2010-11-24T12:24:50.807 に答える
1

クラスの主なポイントは、データと動作をカプセル化し、内部実装を隠し、クリーンでシンプルで便利な API を外部に公開することです。

考慮する必要があるのは、パブリック コントラクト (API) とプライベート データの 2 つです。

  1. プライベート フィールド: これは、セキュリティと整合性のために外部に公開したくないプライベート データです。

  2. プライベート メソッド: コードをより読みやすく保守しやすくするためのユーティリティ関数。

  3. パブリック メソッド: 他の人に公開するコントラクト (インターフェイス、API)。それがあなたのクラスを便利にするものです。

  4. パブリック フィールド: これは使用しないでください。内部データの一部のみを公開します。単純なクラスの場合は問題ないかもしれませんが、相互に依存するフィールドを持つ複雑なクラスの場合、これは大したことではありません。機能を公開するには、パブリック メソッドを使用する必要があります (ポイント 3.)。

于 2010-11-24T12:35:35.900 に答える
0

これらのコメントの多くは、内部/ネストされたクラス、メソッド、およびコンストラクターに適用されます。

基本的に、必要以上に複雑になることなく、アクセスをできるだけ制限したいと考えています。何かを非公開または静的にできる場合は、それをお勧めします。フィールドをファイナルにすることができれば、通常は明瞭度も向上します。

フィールドまたは任意のメンバーが非公開の場合、それが使用されている場所と使用されなくなった時期をすぐに確認できます。

于 2010-11-24T12:28:57.297 に答える