インタビュアー:カプセル化とは何ですか? Java ではどのようにカプセル化を実現していますか?
私: カプセル化は、クライアントから情報を隠すメカニズムです。情報は、データ、実装、またはアルゴリズムの場合があります。アクセス修飾子を使用してこれを実現します。
インタビュアー:これはデータ隠蔽です。Java でカプセル化を実現するにはどうすればよいですか?
私: うーん
具体的な質問:「アクセス修飾子」以外に、Java でカプセル化を実装する方法は何ですか?
インタビュアー:カプセル化とは何ですか? Java ではどのようにカプセル化を実現していますか?
私: カプセル化は、クライアントから情報を隠すメカニズムです。情報は、データ、実装、またはアルゴリズムの場合があります。アクセス修飾子を使用してこれを実現します。
インタビュアー:これはデータ隠蔽です。Java でカプセル化を実現するにはどうすればよいですか?
私: うーん
具体的な質問:「アクセス修飾子」以外に、Java でカプセル化を実装する方法は何ですか?
より一般的には、カプセル化とは、データ (オブジェクトなど) をそのデータに対する操作と一緒にバンドルすることを指します。したがって、データをカプセル化するクラス (フィールド) と、そのデータを操作するためのメソッドがあります。
しかし、カプセル化はあなたの答えと同じように使用されることもあります。実際、データとメソッドをバンドルするポイントの1つは、実装を隠すことです。
メソッドを使用してすべてのフィールドを非公開にするよりも良い答えは、インターフェイスを使用することだと思います。このように、オブジェクトの操作は純粋にインターフェイス コントラクトに基づいており、そのコントラクトを内部的に実装するために使用されるフィールドやヘルパー メソッドに関連付けられることはありません。
一般に、カプセル化とは、類似したアイテムをバンドルすることを意味します。
たとえば、Student
生徒のインスタンス変数と、それらのインスタンス変数に作用する動作/メソッドを 1 か所で使用するクラスを考えてみましょう。
なぜ重要なのですか?コードがコード ベースのあちこちに散らばってしまうのは望ましくありません。
変更を加える必要があるとしたら、すべての場所で (その変更の) バリアントを見つける必要があります。同様のアイテムをバンドルすることで、そのようなシナリオを回避しているだけであり、バンドルされたコードをより集中的にするのにも役立ちます.
外部からデータを保護する方法を提供するだけです。つまり、インスタンス変数を public にすると、誰でもその状態を変更できるということです。しかし、インスタンス変数を private/protected にすると、実際には、外部エンティティによる変更が制限されます。
ここで、どのような点で変数を保護しているのかという疑問が生じます。
カプセル化は、同様のアイテムを配置するために必要な単なるコンテナーであることを再度理解する必要があります。
外の世界へのブラックボックスのように振る舞います。外の世界 (つまり、クライアント/消費者: 私たちのStudent
クラスを使用している) は、クラスの内部の詳細/実装の詳細を知りません。Student
実際には、クラスの内部の詳細/実装の詳細を気にするべきではありません。クライアントアプリケーションで使用できるように、いくつかのメソッド/API が必要なだけです。
したがって、私のポイントは、生徒に関連するすべての行動/変数が、クラスとして呼び出しているブラック ボックスに配置されるということです。クラスの設計者は、クラスのどの要素を非表示にする必要があり、何を外部から非表示にしてはならないかを決める必要があります。
ここで質問に戻ります Java では、変数をプライベートにしています。これは、変数がクラス保護されていることを意味します。パッケージ全体でインスタンス変数にアクセスできるようにしたい場合、それらはパッケージ保護されています。プロジェクトを通して、それらは公開されます。だから私が言いたいのは、データを入れてコンテナに関して隠す、ある種のコンテナが必要なデータを隠すことです。
したがって、 EncapsulationなしではData Hidingは不可能だと感じています。データをなんらかの形のコンテナに入れない限り、データを隠すことはできません。繰り返しになりますが、これをオブジェクト指向言語のコンテキストに当てはめていることを思い出してください。
しかし、はい、カプセル化はデータを隠すことなく可能です。すべてのものを公開すると、その影響を見ることができます。
私はこれをするのが嫌いですが、ウィキペディアから:
プログラミング言語では、カプセル化は、関連しているが異なる 2 つの概念のいずれか、および場合によってはそれらの組み合わせを指すために使用されます。
- オブジェクトの一部のコンポーネントへのアクセスを制限するための言語メカニズム。
- そのデータで動作するメソッド (または他の関数) とデータのバンドルを容易にする言語構造
あなたの説明は最初の概念に沿ったもので、インタビュアーは 2 番目の概念を探していました。
データのカプセル化とは、関連するすべてのプロパティとメソッドを単一のエンティティに保持するメカニズムを指します。
例:車。ハンドル、タイヤ、エンジン、および関連するすべてのものを、 として知られる 1 つの集合体に保持しCar
ます。
プログラミング言語では、カプセル化はクラスで実現されます。one single entity
クラスには、特定のタスクを実行するように設計されたすべてのプロパティと関連メソッドが含まれています。
データの隠蔽とは、重要でない詳細をユーザーから隠し、関連するデータのみを表示することです。
例: 車でブレーキやアクセルを踏むとき、舞台裏で何が起こっているか (どのように速度が上がるのか、どのようにタイヤにブレーキがかかるのか) はわかりません。私たちが知っているのは、望ましい結果を実行するためにブレーキとアクセルがあるということだけです。
プログラミングでは、アクセス修飾子を使用してこれを行います。プライベートメンバーはクラスの外部からはアクセスできず、ユーザーはメンバーのみにpublic
アクセスできます。プライベート メンバーは、クラスのメンバーからのみアクセスできるため、プライベート メンバーがクラスの外部から直接評価されるセキュリティが提供されます。
質問は誤解を招くように見えます。インタビュアー以外の誰もがそれに答えることができるとは思えず、おそらく彼/彼女の答えが間違っている可能性があります. 最も重要なことは、質問が何を評価または発見することになっているのかが明確でないことです。
それでも、私はそれについて少し考えました。以下は、質問に答える私の試みであると私が信じているものです.
Java では、カプセル化は、アクセシビリティ修飾子 (つまり、public、protected、private など) を使用して詳細を隠すことによって実装されます。これらのアクセシビリティ レベルを使用して、情報を隠すレベルを制御します。レベルの制限が緩いほど、変更が発生したときのコストが高くなり、クラスが他の依存クラス (つまり、ユーザー クラス、サブクラス) とより結合されます。
明らかに、カプセル化は状態を隠すだけではありません。Java では、クラスとインターフェイス全体、およびそれらの状態と動作を非表示にすることができます。これにより、API 全体の実装の詳細を非表示にできます。
たとえば、メソッドは実装をArrays.asList()
返しますが、パブリック インターフェイスをList
満たす限り、どの実装かは気にしませんよね? List
メソッドのユーザーである私たちに影響を与えることなく、実装を将来変更することができますが、実際の実装は私たちから隠されています。
ここまでは、カプセル化は、詳細を隠すプログラミング言語の能力に完全に依存しているように見えます。したがって、カプセル化は、アクセス修飾子なしでは実現できないと思われますよね?
しかし、Python のような言語にアクセス修飾子がない場合、どのようにしてカプセル化を実現するのでしょうか? すべてがPythonで公開されていますか? カプセル化できないということですか?
慣例により、コンポーネントのパブリック インターフェイスを定義し、パブリック インターフェイスを介してのみオブジェクトの状態と動作にアクセスするとしたらどうでしょうか。明らかに、このためには、問題領域の抽象化と、それらがユーザーによってどのように消費されることになっているのかを明確に理解する必要があります。
私には、インタビューの質問は、カプセル化を、アクセス修飾子のような言語機能の単なる副産物としてではなく、非常に明確な抽象化の定義に依存する、より広い概念として評価することを意図しているように見えます。
そのため、私の意見では、カプセル化を本当に理解するには、まず抽象化を理解する必要があります。
たとえば、車の概念における抽象化のレベルを考えてみてください。車の内部実装は複雑です。トランスミッションシステム、ブレーキシステム、燃料システムなど、いくつかのサブシステムがあります。
ただし、その抽象化を単純化し、抽象化のパブリック インターフェイスを介して世界中のすべての車とやり取りします。すべての車には方向を制御するハンドルがあり、ペダルを踏むと車が加速して速度を制御し、ペダルを踏むと停止し、ギアスティックがあることを知っています。前後に進むかどうかを制御できるようにします。これらの機能は、車の抽象化のパブリック インターフェイスを構成します。午前中にセダンを運転し、午後に降りて SUV を運転するのと同じようにできます。
ボンネットを開けて、それがどのように機能するかを見ることができないわけではありません。ただし、これらすべての基本機能がボンネットの下でどのように実装されているかの詳細を知っている人はほとんどいません。実際には、車を運転するために詳細を知る必要はありません。これらはすべて、車の抽象化の下にカプセル化されています。抽象化のパブリック インターフェイスを知る必要があるだけです。
自動車に油圧方向指示システムがなかった時代を考えてみてください。ある日、自動車メーカーがそれを発明し、そこから車に搭載することにしました。それでも、これはユーザーが彼らと対話する方法を変えませんでした. せいぜい、ユーザーは指向性システムの使用において改善を経験しました。このような変更が可能になったのは、車の内部実装がカプセル化されていたからです。
これは、指向性システムの実装方法の詳細を非表示にすることで、自動車のパブリック インターフェイスに影響を与えることなく安全に変更できることを明確に示しています。
ここで、自動車メーカーが燃料キャップを車の側面ではなく、車の下に置くことにしたとします。あなたはこれらの新車を買いに行き、ガソリンがなくなったときにガソリンスタンドに行きますが、燃料キャップが見つかりません。突然、車の下にあることに気付きますが、ガソリン ポンプのホースでは手が届きません。今、私たちはパブリック インターフェイスの契約を破りました。そのため、世界全体が崩壊し、物事が期待どおりに機能しないためにバラバラになります。このような変更には数百万の費用がかかります。世界中のすべてのガスポンプを交換する必要があります。カプセル化を破ると、代償を払わなければなりません。
ご覧のとおり、カプセル化の目的は、相互依存を最小限に抑え、変更を容易にすることです。実装の詳細の公開を最小限に抑えることで、カプセル化を最大化します。クラスの状態には、そのパブリック インターフェイスを介してのみアクセスする必要があります。
カプセル化の利点は、ユーザーに影響を与えずに物事を変更できることです。
この究極の目標は、綿密な計画と設計にかかっていると言えます。Java では、アクセス修飾子はこれらのアイデアを実現する方法ですが、この機能が存在しない言語では、カプセル化を実現することも同様に可能です。
カプセル化: カプセル化は OOPS の柱の 1 つであり、データの隠蔽と抽象化という他の 2 つの用語のスーパーセットでもあります。(データ隠蔽、用語が指すように..データは変数にのみ格納できます。データを外部世界から隠すために、データ隠蔽の概念を使用します。Public、Private、Protected は、データ隠蔽のために提供された 3 つのアクセス修飾子です。デフォルトはパッケージに限定され、継承されたクラスに限定されて保護されます。) ** プライベート変数はクラス内でのみアクセス可能です。つまり、内部クラスが存在する場合、プライベート変数も直接呼び出すことができます。静的内部クラスのみが静的変数を呼び出すことができます。
今度は抽象化(無形の意味)に来ます。抽象化は、実装をユーザーから隠し、最終結果のみを提供するプロセスとも見なされます。例: 「体重」プロパティを持つ人物クラスがあります。人の体重が 0 未満であることは認められないため、このプロパティは非常に扱いにくいものです。また、500kgを超えるものはお受けできません。したがって、これらの実装を非表示にすると、setter メソッドになります。実装の詳細を隠しているこのことは、抽象化です。
** そして完全なパッケージ、つまりオブジェクトを非公開にし、setter と getter でロジックを実装することを ENCAPSULATION と呼びます。
私の理解から単純化するために、多くの議論がすでに行われているのを見ました:
カプセル化 オブジェクトの動作が API を通じてのみ影響を受けることを保証します。無関係なコンポーネント間に予期しない依存関係がないようにすることで、1 つのオブジェクトへの変更がシステムの他の部分にどの程度影響するかを制御できます。アクセス修飾子を使用してカプセル化を実現できます。
情報の隠蔽 オブジェクトがその機能を API の抽象化の背後に実装する方法を隠します。目の前のタスクに関係のない低レベルの詳細を無視することで、より高い抽象化で作業できます。設計レベルでの抽象化を使用して、データの隠蔽を実現できます。
外部クラス メンバーからの直接アクセスからデータを隠し、適切な検証を通じてパブリックにアクセス可能なセッターおよびゲッター メソッドを介してのみアクセスを提供することによってクラスを定義するプロセスは、カプセル化と呼ばれます。
カプセル化とは、データ メンバーとメソッド (動作) を 1 つのユニットにバインドし、[カプセル化 = データの隠蔽 + 抽象化] と言うことができるように、ユーザーが必要とするだけの情報を簡単に提供することを意味します。
クラスはJavaで完全にカプセル化された要素です
データの隠蔽とは、データ変数をプライベートとして宣言して不正アクセスから保護することを意味しますが、検証のためにパブリック セッターおよびゲッター メソッドを提供している場合。
抽象化は、オブジェクトと対話するために必要なものを言います。
カプセル化とは、オブジェクトのプロパティ、状態、および動作を、クラスと呼ばれる単一の論理単位にカプセル化することを意味します。
データ隠蔽とは、オブジェクトの内部実装を隠蔽することは、プライベート メソッドとプロパティ、つまり状態を維持するために使用するオブジェクトを意味することを意味します。
カプセル化 カプセル化は、データとデータを操作する関数を結合し、外部の干渉や誤用から両方を保護するオブジェクト指向プログラミングの概念です。データのカプセル化は、データ隠蔽という重要な OOP 概念につながりました。
クラスが呼び出しコードに内部オブジェクト データへのアクセスを許可せず、メソッドを介したアクセスのみを許可する場合、これはカプセル化と呼ばれる抽象化または情報隠蔽の強力な形式です。一部の言語 (Java など) では、クラスにアクセス制限を明示的に適用できます。たとえば、private キーワードを使用して内部データを示し、public キーワードを使用してクラス外のコードで使用することを目的としたメソッドを指定します。メソッドは、public、private、または protected などの中間レベル (同じクラスとそのサブクラスからのアクセスを許可しますが、異なるクラスのオブジェクトからのアクセスは許可しません) として設計することもできます。他の言語 (Python など) では、これは規則によってのみ強制されます (たとえば、プライベート メソッドにはアンダースコアで始まる名前がある場合があります)。カプセル化により、外部コードがオブジェクトの内部動作に関与するのを防ぎます。これにより、コードのリファクタリングが容易になります。たとえば、クラスの作成者は、外部コードを変更することなく、そのクラスのオブジェクトが内部でデータを表す方法を変更できます (「パブリック」メソッド呼び出しが同じように機能する限り)。また、プログラマーが特定のデータセットに関係するすべてのコードを同じクラスに配置することを奨励します。これにより、他のプログラマーが簡単に理解できるように編成されます。カプセル化は、デカップリングを促進する技術です。メソッド呼び出しも同じように機能します)。また、プログラマーが特定のデータセットに関係するすべてのコードを同じクラスに配置することを奨励します。これにより、他のプログラマーが簡単に理解できるように編成されます。カプセル化は、デカップリングを促進する技術です。メソッド呼び出しも同じように機能します)。また、プログラマーが特定のデータセットに関係するすべてのコードを同じクラスに配置することを奨励します。これにより、他のプログラマーが簡単に理解できるように編成されます。カプセル化は、デカップリングを促進する技術です。