カプセル化と抽象化の簡単な定義を以下に示します。
抽象化:
Javaの抽象化プロセスは、特定の詳細を非表示にし、オブジェクトの本質的な機能のみを表示するために使用されます。つまり、オブジェクト(インターフェイス)の外側のビューを処理します。異なるサイト間でこれについて見られる唯一の良い例は、インターフェースです。
カプセル化:
その基本は、private、public、protectedなどの修飾子を使用してオブジェクトの状態を非表示にすることです。必要な場合にのみ、パブリックメソッドを通じて状態を公開します。
private
、public
のような修飾子を使用して達成することは、抽象概念に過ぎない外部の世界から不要な詳細を隠します
したがって、上記の説明から、カプセル化は抽象化の一部であるように見えますが、抽象化のサブセットであると言えます。しかし、なぜ抽象化のみを扱うことができるのにカプセル化用語が発明されたのでしょうか?それらを区別する大きな違いがあるはずですが、ネット上の資料のほとんどは、両方についてほぼ同じことを言っています。
この質問は以前にもこのフォーラムで提起されましたが、特定の疑問を抱いて再度投稿しています。一部の回答は、抽象化が概念であり、カプセル化が実装であるとも述べています。しかし、私はこれを購入しません-それが本当なら、私たちを混乱させるためにこれらの2つの異なる概念が提供されていると考えることができます。
更新:-5年後、私はこの投稿と以下の回答に基づいた要点である自分の答えを思いつきました
カプセル化は、抽象化の一部として使用される戦略です。カプセル化はオブジェクトの状態を指します-オブジェクトは状態をカプセル化し、外部から隠します。クラスの外部ユーザーはそのメソッドを介してクラスとやり取りしますが、クラスの状態に直接アクセスすることはできません。そのため、クラスは、その状態に関連する実装の詳細を抽象化します。
Abstractionは、より一般的な用語であり、(とりわけ)サブクラス化によっても実現できます。たとえば、標準ライブラリのインターフェイスList
は、位置によってインデックス付けされた一連のアイテムの抽象化です。List
の具体例は、ArrayList
またはLinkedList
です。 List
と対話するコードは、使用しているリストの種類の詳細を抽象化します。
抽象化は、カプセル化によって基本的な状態を隠さずに不可能な場合がよくあります。クラスが内部状態を公開する場合、内部の動作を変更できないため、抽象化できません。
Abstractionは、重要なことに焦点を合わせるために、何かをより単純な用語で説明する、つまり詳細を抽象化する概念です(これは、たとえば芸術家が色や形などの画像の構成要素)。継承階層を使用することで、同じアイデアがOOPに変換されます。継承の階層では、抽象概念が最上位にあり、より具体的なアイデアが最下位にあり、抽象概念に基づいています。最も抽象的なレベルでは、実装の詳細はまったくなく、おそらく非常に少数の共通点があり、抽象化が減少するにつれて追加されます。
例として、最上部は単一のメソッドを備えたインターフェースであり、次のレベルはいくつかの抽象クラスを提供します。これらの抽象クラスは、最上位に関する詳細の一部を埋めるかもしれないが、独自の抽象メソッドを追加することで分岐します、これらの抽象クラスのそれぞれは、残りのすべてのメソッドの実装を提供する具象クラスです。
カプセル化はテクニックです。抽象化を支援するためであってもなくてもよいが、それは確かに情報の隠蔽および/または組織に関するものである。それはデータと関数が何らかの方法でグループ化されることを要求します-もちろん良いOOPプラクティスは抽象化によってグループ化されることを要求します。ただし、保守性などに役立つ他の用途もあります。
カプセル化は抽象化の一部であるか、抽象化のサブセットと言うことができます
それらは異なる概念です。
抽象化とは、オブジェクトの不要/重要でない属性をすべて整理し、ドメインに最適な特性のみを保持するプロセスです。
例えば。個人の場合:姓と名とSSNを保持することにします。年齢、身長、体重などは無関係であるとして無視されます。
抽象化は、設計の始まりです。
カプセル化は非表示不要カプセルまたはユニット内のデータ
抽象化は表示必須オブジェクトの特徴
カプセル化は、外部クラスおよびインターフェイスからそのメンバーを隠すために使用されます。c#.like public、private、protectedなどで提供されるアクセス修飾子の使用例:
Class Learn
{
private int a; // by making it private we are hiding it from other
private void show() //class to access it
{
console.writeline(a);
}
}
ここでは、ユニットまたはカプセル、つまりクラスにラップデータがあります。
抽象化は、カプセル化の正反対です。
抽象化は、重要で関連性のあるデータをユーザーに示すために使用されます。最高の実世界の例携帯電話では、カメラ、mp3プレーヤー、通話機能、録音機能、マルチメディアなどのさまざまなタイプの機能が表示されます。内部エンジニアリングではなく関連情報のみが表示されるため、抽象化されます。
abstract class MobilePhone
{
public void Calling(); //put necessary or essential data
public void SendSMS(); //calling n sms are main in mobile
}
public class BlackBerry : MobilePhone // inherited main feature
{
public void FMRadio(); //added new
public void MP3();
public void Camera();
public void Recording();
}
抽象化は非常に一般的な用語であり、ソフトウェアの抽象化はオブジェクト指向言語に限定されません。辞書の定義:「具体的な現実、特定のオブジェクト、または実際のインスタンスとは別に、一般的な品質または特性として何かを考慮する行為」。
アセンブリ言語は、マシンコードの抽象化と考えることができます-アセンブリは、マシンコードの本質的な詳細と構造を表現しますが、使用されるオペコード、メモリ内のコードのレイアウト、ジャンプへのジャンプについて考える必要がありません正しい住所など.
オペレーティングシステムのAPIは、基になるマシンの抽象化です。コンパイラは、アセンブリ言語の詳細からユーザーを保護する抽象化レイヤーを提供します。オペレーティングシステムに組み込まれたTCP/IPスタックは、ネットワーク上でビットを送信する詳細を抽象化します。生のシリコンに至るまで、CPUを設計した人たちは、電子が半導体結晶をどのように移動するかを抽象化した「ダイオード」と「トランジスタ」で書かれた回路図を使用して設計しました。
ソフトウェアでは、すべては抽象化です。現実の一部をシミュレートまたはモデル化するプログラムを構築しますが、必然的に、モデルは常に「本物」の詳細を抽象化します。抽象化のレイヤー上にレイヤーを構築します。これが私たちが何かを達成する唯一の方法だからです。 (たとえば、数独ソルバーを作成しようとして、半導体結晶のみを使用して設計しなければならなかったと想像してください。「OK、ここにN型シリコンが必要です...」)
これに対して、「カプセル化」は非常に限定的な用語です。この質問に対する他の回答のいくつかは、すでに適切な定義を与えています。
さらに詳細が必要だと感じてから5年後に自分の質問に答える
抽象:
技術的定義:-抽象化は、不要な詳細(複雑または単純)を隠し、オブジェクトの本質的な特徴のみを表示する概念です。ここに実装はありません
それが実際に意味するもの:-私の会社が従業員が顧客に接続できるように何らかの媒体/デバイスが必要だと言うとき。これは、デバイス/メディアが電話、インターネット、スカイプ、または直接または電子メールなどになる可能性があるため、abstaction(Javaのインターフェイスのような)の最も純粋な形式です。デバイス/メディアの核心には入りません
私の会社では、従業員が音声通話で顧客に接続できるように、何らかのメディア/デバイスが必要だと言ってもです。また、私は抽象的な話をしていますが、デバイス/メディアは電話やスカイプなどである可能性があるため、少し低レベルです
従業員が音声通話を介して顧客に接続できるように、会社に電話が必要だと言いました。また、私は抽象的な話をしていますが、電話はiphoneやsamsungまたはnokiaなどの会社のものである可能性があるため、少し低レベルです
カプセル化:-基本的に、private、public、protectedなどの修飾子の助けを借りてオブジェクトの状態(情報)を隠すことについて、状態を公開します必要な場合にのみパブリックメソッド。
それが実際に意味すること:-今、私の会社が従業員が音声通話を介して顧客に接続できるようにiPhoneが必要だと言ったとき、コンクリートオブジェクト(iphoneなど)。ここでもiPhoneの核心部分には触れていませんが、iPhoneにはデバイス/メディアにはない状態/具体的な情報/実装が関連付けられています。具体的なオブジェクトと言うと、実際には、(Java抽象クラスのように完全ではない)実装/情報が関連付けられているオブジェクトを意味します。
そのため、iphoneは実際に、ここでカプセル化を戦略として使用して、状態/情報を隠し、公開する必要があると思われるもののみを公開します。したがって、抽象化とカプセル化の両方は、いくつかの不必要な詳細を隠しますが、概念レベルでの抽象化と実際の実装レベルでのカプセル化
これは、この投稿と以下の回答に基づく要点です
カプセル化-クラスのコンポーネントを非表示にして、外部からの直接アクセスを防ぐプロセス。これは、「private」修飾子を使用して、他のクラスまたはオブジェクトから一部のクラスメンバー(データフィールドまたはメソッド)への直接アクセスを防止する一方で、パブリックメンバー(インターフェース)によるこれらのプライベートメンバーへのアクセスを提供することで実現されます。それにより、クラスメンバーは、皮膚またはシールドの下に隠された/カプセル化された人間の臓器として保護されます。
Abstraction-「プログラムのタスクで興味深いコンポーネントのみをクラスに含める必要がある」というOOPプログラムを記述する際には、原則に従う必要があります。例:オブジェクトの学生には、人間としての多くのキャラクターがあります:名前、年齢、体重、髪の色、目の色など。しかし、OOPでクラスを作成する場合、学生と作業する必要があります学生データベースに本当に重要な文字のみを含めます。名前、年齢、専門性、レベル、マークなどC++では、クラスのメソッドで修飾子「virtual」を使用して抽象クラスを作成できます。直接使用できませんが、タスクから必要なメンバーを追加することで、他のクラスを派生させ、そのメンバーの実装を作成できます。
これは私がそれを理解した方法です:
オブジェクト指向プログラミングでは、classesと呼ばれるものがあります。それらは何のため?それらは、いくつかの状態を保存し、その状態を変更するためのメソッドを保存します。つまり、それらはencapsulating状態とそのメソッドです。
It(class)は、それ自体またはそのコンテンツの可視性を気にしません。 状態またはいくつかのメソッドを隠すを選択した場合、それはinformation hiding。
ここで、継承のシナリオを取り上げます。基本クラスと、いくつかの派生(継承)クラスがあります。では、ここで基本クラスは何をしているのでしょうか? abstracting派生クラスからいくつかのものを取り出します。
それらはすべて違いますよね?しかし、それらを混ぜ合わせて、優れたオブジェクト指向プログラムを作成します。それが役に立てば幸い :)
抽象化の線引きコンテキスト固有の簡略化された何かの表現。文脈的に無関係な詳細は無視され、文脈的に重要な詳細が含まれます。
カプセル化制限何かの部分への外部アクセスおよびバンドル状態を使用するプロシージャによるその状態。
たとえば、人々を取ります。手術の文脈では、有用な抽象化は人の宗教的信念を無視し、人の体を含みます。さらに、人々はそれらの記憶を使用する思考プロセスで記憶をカプセル化します。抽象化はカプセル化する必要はありません。たとえば、人の絵は、その部分を隠したり、手順をその状態に束ねたりしません。また、カプセル化に関連する抽象化は必要ありません。たとえば、実際の人(抽象的な人ではない)は、代謝で臓器をカプセル化します。
別の方法で理解してみましょう。
抽象化が存在しない場合に発生する可能性があるものと、カプセル化が存在しない場合に発生する可能性があるもの。
抽象化が存在しない場合、オブジェクトの使用量は少ないと言えます。オブジェクトを識別することも、その機能にアクセスすることもできません。テレビの例を見てみましょう。電源を入れたり、チャンネルを変更したり、音量を上げたり下げたりするオプションがない場合は、テレビの使用方法と使用方法を教えてください。
カプセル化が存在しないか、適切に実装されていない場合、オブジェクトを誤用する可能性があります。そこでデータ/コンポーネントが誤用される可能性があります。 TVの同じ例を見てください。TVのボリュームにカプセル化が行われていない場合、ボリュームコントローラーはその限界(0〜40/50)を下回ったり、超えたりすることで誤用される可能性があります。
注:これを共有しています。ここが良い答えではないという意味ではなく、私が簡単に理解したからです。
回答:
クラスが概念化された場合、コンテキストを指定して、そのクラスで使用できるプロパティは何ですか。動物園のコンテキストでクラスAnimalを設計している場合、家畜または野生を表すanimalTypeの属性を持っていることが重要です。別のコンテキストでクラスを設計する場合、この属性は意味をなさない場合があります。
同様に、クラスで行う動作は何ですか?ここでも抽象化が適用されます。ここで何が必要で、何が過剰摂取になりますか?次に、クラスからいくつかの情報を切り取りました。このプロセスは抽象化を適用しています。
カプセル化と抽象化の違いを尋ねると、 encapsulation は概念として抽象化を使用します。それでは、カプセル化のみですか。いいえ、抽象化は、継承と多態性の一部として適用される概念ですらあります。
Go このトピックの詳細については、こちらをご覧ください。
カプセル化は、外部エンティティからのオブジェクト/インスタンスの内部動作を崩壊から保護します。そのため、提供されているデータがインスタンス/オブジェクトの内部システムに影響を与えてその存続を維持することを確認するコントロールを提供する必要があります。
良い例として、除算器は、2つのインスタンス変数の被除数と除数、およびメソッドgetDividedValueを持つクラスです。
除数が0に設定されている場合、内部システム/動作(getDivided)が破損することを考えてください。
そのため、メソッドを介して例外をスローすることにより、オブジェクトの内部動作を保護できます。
簡単な文で、私は言うことができます:抽象化の本質は、本質的でない詳細を省きながら、本質的なプロパティを抽出することです。しかし、なぜ重要でない詳細を省略する必要があるのでしょうか?重要な動機は、変化のリスクを防ぐことです。抽象化はカプセル化と同じであると考えるかもしれません。ただし、カプセル化とは、詳細を隠すことなく、コンテナ内に1つ以上のアイテムを囲むことを意味します。 「カプセル化されたものもすべて隠されていた」という議論をした場合。これは明らかに真実ではありません。たとえば、情報がレコード構造および配列内にカプセル化されている場合でも、この情報は通常、非表示になりません(他のメカニズムによって非表示にされない限り)。