カプセル化と抽象化の正確な違いは何ですか?
ここでのほとんどの回答はOOPに焦点を当てていますが、カプセル化はもっと早く始まります:
すべての関数は カプセル化;擬似コードで:
point x = { 1, 4 }
point y = { 23, 42 }
numeric d = distance(x, y)
ここで、distance
は、平面内の2点間の(ユークリッド)距離の計算をカプセル化します:実装の詳細を隠します。これは、純粋で単純なカプセル化です。
抽象化 は、一般化のプロセスです:具体的な実装を行い、作成します多少関連しているが、さまざまな種類のデータに適用できます。抽象化の古典的な例は、データをソートするCのqsort
関数です。
qsort
についてのことは、並べ替えるデータを気にしないということです。実際、はどのデータを並べ替えるかわからないむしろ、その入力タイプはタイプレスポインター(void*
)であり、これはCの「データのタイプを気にしない」という意味です(これはタイプ消去とも呼ばれます)。重要な点は、データ型に関係なく、qsort
の実装が常に同じであることです。 が変更する必要がある唯一のものは、データ型ごとに異なる比較関数です。したがって、qsort
は、ユーザーが関数引数として上記の比較関数を提供することを期待しています。
カプセル化と抽象化は非常に密接に関連しているので、それらが本当に不可分であることを指摘することができます。実際には、これはおそらく真実です。とはいえ、これは抽象化ではないカプセル化です。
class point {
numeric x
numeric y
}
ポイントの座標をカプセル化しますが、論理的にグループ化する以外に、それらを実質的に抽象化しません。
そして、カプセル化ではない抽象化の例を次に示します。
T pi<T> = 3.1415926535
これは、特定の値(π)を持つジェネリック変数pi
であり、変数の正確な型は宣言で考慮されません。確かに、私は実際のコードでこのようなものを見つけるのは難しいと思います:抽象化は事実上常にカプセル化を使用します。ただし、上記のdoesは、C++(14)に variable templates (= generic変数のテンプレート);やや複雑な構文、例えば:
template <typename T> constexpr T pi = T{3.1415926535};
カプセル化は実装の詳細を隠していますが、これは一般的または特殊な振る舞いのためのものであるかもしれません。
抽象化は一般化を提供します(たとえば、一連の動作に対して)。
これが良い読みです。 Object AgencyのEdward V. Berardによる抽象化、カプセル化、および情報隠蔽 。
多くの答えとその例は誤解を招くものです。
カプセル化 は、データおよびそのデータを操作する関数のパッキングです。単一のコンポーネントにまとめて、オブジェクトのコンポーネントの一部へのアクセスを制限します。
カプセル化とは、オブジェクトの内部表現が一般に、そのオブジェクトの定義の外側にあるビューから隠されていることを意味します。
抽象化 は、実装の詳細を含めずに基本機能を表すメカニズムです。
カプセル化: - 情報隠蔽。
抽象化: - 実装隠蔽。
例:
class foo{
private:
int a, b;
public:
foo(int x=0, int y=0): a(x), b(y) {}
int add(){
return a+b;
}
}
foo
クラスのオブジェクトの内部表現はクラスの外に隠されています。 - >カプセル化.foo
のオブジェクトのアクセス可能なメンバー(データ/関数)は制限されており、そのオブジェクトからのみアクセスできます。
foo foo_obj(3, 4);
int sum = foo_obj.add();
メソッドadd
の実装は隠されています。 - >抽象化.
カプセル化は箱にいくつかのものを入れてあなたに覗き穴を与えます。これはあなたがギアでこするのを防ぎます。
抽象化フラットアウトは、物事に歯車、ラチェット、フライホイール、または核心があるかどうかなど、重要ではない詳細を無視します。彼らはただ「行く」
カプセル化の例:
抽象化の例:
抽象化は一般化された用語です。すなわち、カプセル化は抽象化のサブセットです。
例2
ソリューションアーキテクトは、ソリューション全体の高レベル抽象技術設計を作成する人です。この設計は、実装のために開発チームに渡されます。
ここでは、ソリューションアーキテクトは抽象として機能し、開発チームはカプセル化として機能します。
多くの良い答えが上で提供されていますが、私はここで私の(Java)視点を提示するつもりです。
データのカプセル化 は、クラス内の論理的にグループ化されたデータのアクセスをラップしてアクセスを制御することを意味します。通常、別のキーワード - データ非表示 に関連付けられています。これはJavaで アクセス修飾子 を使って実現されます。
簡単な例としては、プライベート変数を定義して、getterメソッドおよびsetterメソッドを使用してアクセスできるようにするか、またはクラス内で使用するだけのようにメソッドをプライベートにする方法があります。ユーザーがこれらのメソッドや変数について知る必要はありません。
注 :カプセル化はすべてデータを隠すことだけを目的としていると誤解しないでください。カプセル化と言えば、関連するデータと振る舞いをグループ化、パッケージ化、またはバンドルすることに重点を置く必要があります。
データ抽象化 一方、下にある複雑なロジックがユーザーに公開されないように一般化する概念です。 Javaでは、これは インタフェース および 抽象 クラスを使用することによって実現されます。
例 -
インタフェースAnimal があり、それに関数 makeSound() があるとしましょう。このインタフェースを実装する2つの具象クラス Dog と Cat があります。これらの具象クラスには、makeSound()関数の個別の実装があります。それでは、動物がいるとしましょう(これは外部モジュールから取得します)。ユーザーが知っているのは、それが受信しているオブジェクトは動物であり、動物の音を印刷するのはユーザーの責任だということです。強引な方法の1つは、 識別 その型に受け取ったオブジェクトをチェックし、次に 型キャスト その動物の型にして call makeSound()を呼び出すことです。しかし、もっと良い方法は を抽象化することです 。 多相参照 としてAnimalを使用し、それに対してmakeSound()を呼び出します。 runtime 実際のオブジェクト型が適切であるかに応じて、関数が呼び出されます。
詳細 はこちら 。
複雑なロジックはタッチパッドにカプセル化されている回路基板にあり、それをユーザに抽象化するためにNiceインタフェース(ボタン)が提供されています。
シモンズ:上記のリンクは私の個人的なブログにあります。
あなたが車を運転するときのように、あなたはアクセルペダルが何をするか知っています、しかしそれがカプセル化されているのであなたはそれの後ろのプロセスを知らないかもしれません。
C#で例を挙げましょう。整数があるとします。
int Number = 5;
string aStrNumber = Number.ToString();
number.ToString()のように、数字5の文字表現を返し、それを文字列オブジェクトに格納するメソッドを使用できます。このメソッドは、実行方法ではなく実行方法を示します。
これらは、コンピュータサイエンスやプログラミングに固有のものではない、ややあいまいな概念です。他の人がこれらの重要な概念を理解するのを助けるかもしれないいくつかの追加の考えを提供したいです。
カプセル化 - 必要なインターフェースを公開しながら、システムの特定の部分へのアクセスを隠したり制限したりします。
抽象化 - 具体的な現実、特定のオブジェクト、または実際のインスタンスとは別に、特定の特性が削除されたものを検討することで、複雑さを軽減します。
主な類似性は、これらのテクニックが理解度と有用性を向上させることを目的としていることです。
主な違いは、抽象化が物事をより単純に表現する手段である(表現をより広く適用可能にするため)のに対し、カプセル化は他のものが何かと対話する方法を変更する方法。
これがカプセル化の例です。これにより、状況がより明確になります。
ここには、 Arduino Unoと、エンクロージャ内にArduino Unoがあります。 Enclosureは、カプセル化とは何かについての素晴らしい表現です。
カプセル化は、特定のコンポーネントを外部の影響や知識から保護するとともに、他のものとのインタフェースをとるべきコンポーネントを公開することを目的としています。プログラミング用語では、これは 情報隠蔽 を含みますが、 アクセス修飾子 。特定の変数やプロパティを読み書きできる範囲を変更します。
しかしそれ以外にも、カプセル化はこれらの外部インターフェースをより効果的に提供することも目的としています。 Arduinoの例では、これにはNiceボタンと画面が含まれているため、ユーザーとデバイスとの対話がはるかに簡単になります。それらは、デバイスの動作に影響を及ぼし、そうでなければはるかに困難になるであろうその動作についての有用な情報を得るための簡単な方法をユーザに提供する。
プログラミングでは、これにはさまざまなコンポーネントをfunction
、class
、object
などの分離可能な構成要素にグループ化することが含まれます。それはまた、それらの構成要素と相互作用する手段、およびそれらについての有用な情報を得るための方法を提供することを含む。
カプセル化は、多くの追加の方法でプログラマーを支援しますが、その中でも特にコードの保守性とテスト容易性が向上します。
ここでの他の多くの答えは抽象化を一般化と定義していますが、私は個人的に定義が誤っていると思います。一般化は実際には特定のタイプの抽象化であり、その逆ではないと思います。言い換えれば、すべての一般化は抽象化ですが、すべての抽象化はnotは必ずしも一般化です。
抽象化について考えるのが好きです:
画像に木があると思いますか。たぶんあなたはそうなるでしょう。しかし、それは本当に木なのか?まあ、もちろん違います!それは我々が木と呼ぶかもしれない何かのように見えるように作られたピクセルの束です。それは本当の木の抽象化を表すと言えるでしょう。ツリーの視覚的な詳細がいくつか省略されていることに注意してください。また、成長したり、水を消費したり、酸素を生成することはありません。どうした?それはあなたのコンピュータのメモリの中のバイト数で表されるスクリーン上の色の束です。
そしてこれが抽象化の本質です。理解しやすくするために、物事を単純化する方法です。あなたの頭を通過するすべてのアイデアは現実の抽象化です。木のあなたの精神的なイメージは、このjpegより実際の木ではありません。
プログラミングでは、成長を模倣し、水を消費し、そして酸素を生成するためのメソッドを持つTree
クラスを作成することによって、これを利用することができます。私たちの創造は実際の木の私たちの経験を表すものであり、そして私たちの特定のシミュレーションのために私たちが本当に気にする要素のみを含みます。私たちは何かの経験をバイトと数学で表現する方法として抽象化を使います。
プログラミングの抽象化によって、いくつかの「具体的な」オブジェクト型(実際に存在する型)間の共通点を考慮し、それらの共通点を一意のエンティティ内で定義することもできます。例えば、私たちのTree
クラスは、すべての植物のようなクラスに適用可能ないくつかのプロパティとメソッドを持っているabstract class Plant
から継承するかもしれませんが、remove特定のもの植物の種類ごとに。これにより、コードの重複を大幅に減らすことができ、保守性が向上します。
abstract class
と普通のclass
の実際的な違いは、概念的には「本当の」abstract class
のインスタンスがないということです。 Plant
オブジェクトを作成するのは意味がありません。すべての "本物の" Plant
は、より具体的なタイプのPlant
でもあります。
また、プログラムをより現実的なものにしたい場合は、Tree
クラス自体が抽象的すぎる可能性があるという事実を考慮する必要があります。実際には、すべてのTree
はより具体的なTree
の型であるため、Birch
、Maple
など、おそらく現在はabstract
、Tree
クラスを継承するクラス用のクラスを作成できます。
抽象化のもう1つの良い例は、 Java仮想マシン(JVM) です。これは、仮想または抽象を提供します。 Javaコードを実行するコンピューター。それは本質的にシステムのプラットフォーム特有のコンポーネントの全てを取り除き、特にいかなるシステムにも関係なく「コンピュータ」の抽象的なインターフェースを提供する。
カプセル化は抽象化とは異なり、「実際の」または「正確な」何かがどのようなものであるかとは関係がありません。という要素を単純にしたり、より広く適用したりすることはできません。そうではなく、同様の目的を達成するために、hide/というコンポーネントを使用することができます。
カプセル化:オブジェクトの実際のユーザーから、望ましくない/予期しない/適切な実装の詳細を隠しています。例えば.
List<string> list = new List<string>();
list.Sort(); /* Here, which sorting algorithm is used and hows its
implemented is not useful to the user who wants to perform sort, that's
why its hidden from the user of list. */
抽象化:一般化を提供する方法であり、したがって広大な多様性のオブジェクトを扱う一般的な方法です。例えば.
class Aeroplane : IFlyable, IFuelable, IMachine
{ // Aeroplane's Design says:
// Aeroplane is a flying object
// Aeroplane can be fueled
// Aeroplane is a Machine
}
// But the code related to Pilot, or Driver of Aeroplane is not bothered
// about Machine or Fuel. Hence,
// pilot code:
IFlyable flyingObj = new Aeroplane();
flyingObj.Fly();
// fighter Pilot related code
IFlyable flyingObj2 = new FighterAeroplane();
flyingObj2.Fly();
// UFO related code
IFlyable ufoObj = new UFO();
ufoObj.Fly();
// **All the 3 Above codes are genaralized using IFlyable,
// Interface Abstraction**
// Fly related code knows how to fly, irrespective of the type of
// flying object they are.
// Similarly, Fuel related code:
// Fueling an Aeroplane
IFuelable fuelableObj = new Aeroplane();
fuelableObj.FillFuel();
// Fueling a Car
IFuelable fuelableObj2 = new Car(); // class Car : IFuelable { }
fuelableObj2.FillFuel();
// ** Fueling code does not need know what kind of vehicle it is, so far
// as it can Fill Fuel**
抽象化とカプセル化の違い.
抽象化:何かを単純化された/異なる方法で提示するという考え。それは理解しやすく使いやすいか、状況に関係しているかのどちらかです。
電子メールを送信するクラスを考えてみましょう。抽象クラスを使用して自分自身を何らかのメッセンジャーボーイとして表示します。そのため、emailSender.send(mail、recipient)を呼び出すことができます。それが実際に何をしているか - POP3/SMTPの選択、サーバーの呼び出し、MIME変換などは抽象化されています。あなたはあなたのメッセンジャーボーイを見るだけです。
カプセル化:オブジェクトに固有のデータやメソッドを保護したり隠したりするという考え方。それは何かを独立した絶対確実なものにすることをもっと扱います。
例えば私を連れていって。私は自分の心拍数を世界の他の地域からカプセル化します。他の人がその変数を変更したくないし、私が機能するために他の人が変数を設定する必要もないからです。それは私にとって非常に重要ですが、あなたはそれが何であるかを知る必要はありません、そしてあなたはおそらくとにかく気にしません。
周りを見てみると、あなたが触れたものはほとんどすべて抽象化とカプセル化の両方の例です。例えば、あなたの電話はあなたがあなたの言うことを理解してそれを他の誰かに話すことができるという抽象概念をあなたに提示します - GSM、プロセッサアーキテクチャ、無線周波数、そしてあなたが理解できないまたは気にしない他の何百ものものをカバーします。シリアル番号、ID番号、周波数など、あなたからの特定のデータもカプセル化されます。
それはすべて、世界をより住みやすい場所にします。D
抽象化:必要な情報だけが表示されます。コンピュータの電源を入れる例に注目しましょう。ユーザーは、システムがまだロードされている間に何が起こっているのかを知る必要はありません(その情報はユーザーから隠されています)。
もう1つの例、ATMの例を見てみましょう。顧客は、マシンがどのようにPINを読み取り、取引を処理するかを知る必要はありません。彼がする必要があるのは、PINを入力し、現金を取り、出て行くことだけです。
カプセル化:クラスの機密データを隠すことを扱い、そのため一部を民営化します。これは、外部からのアクセスを許可しないことによって、一部の情報をそのクライアントに対して非公開にする方法です。
Abstraction
およびEncapsulation
一般化された単一の例を使用する----------------------------------------- -------------------------------------------------- -----------------------------------------
私たちは皆、複雑な問題の計算に電卓を使っています!
もう一つの例:
このような不変のRectangleクラスを作成したとします。
class Rectangle {
public:
Rectangle(int width, int height) : width_(width), height_(height) {}
int width() const { return width_; }
int height() const { return height_; }
private:
int width_;
int height_;
}
カプセル化された幅と高さ(アクセスはどういうわけか制限されています)は明らかになりましたが、抽象化された何もしていません。長方形が座標空間のどこにあるかは無視されますが、これは例の欠陥です。
適切な抽象化は通常、適切なカプセル化を意味します。
良い抽象化の例は、一般的なデータベース接続クラスです。その公開インターフェースはデータベースにとらわれず、非常に単純ですが、それでも私は自分の接続でやりたいことができるようになります。そして、あなたは?クラスにはすべての低レベルのハンドルと呼び出しが含まれている必要があるため、そこにカプセル化もあります。
抽象化:抽象化は、機能のWhat
部分を表示することを意味します。
カプセル化:カプセル化とは、機能のHow
部分を隠すことです。
とても簡単な例を見てみましょう
/// <summary>
/// We have an Employee class having two properties EmployeeName and EmployeeCode
/// </summary>
public class Employee
{
public string EmplpyeeName { get; set; }
public string EmployeeCode { get; set; }
// Add new employee to DB is the main functionality, so are making it public so that we can expose it to external environment
// This is ABSTRACTION
public void AddEmployee(Employee obj)
{
// "Creation of DB connection" and "To check if employee exists" are internal details which we have hide from external environment
// You can see that these methods are private, external environment just need "What" part only
CreateDBConnection();
CheckIfEmployeeExists();
}
// ENCAPLUSATION using private keyword
private bool CheckIfEmployeeExists()
{
// Here we can validate if the employee already exists
return true;
}
// ENCAPLUSATION using private keyword
private void CreateDBConnection()
{
// Create DB connection code
}
}
コンソールアプリケーションのプログラムクラス
class Program
{
static void Main(string[] args)
{
Employee obj = new Employee();
obj.EmplpyeeName = "001";
obj.EmployeeCode = "Raj";
// We have exposed only what part of the functionality
obj.AddEmployee(obj);
}
}
特定のオブジェクトのデータを意図的または偶発的な外部関数による誤用から保護するためのメカニズムは、「データのカプセル化」と呼ばれます。
背景の詳細や説明を含めずに本質的な特徴を表現することは、抽象化として知られています。
スタックの例を見てみましょう。配列またはリンクリストを使用して実装できます。しかしそれがサポートする操作はプッシュとポップです。
現在、抽象化は、Pushおよびpopインターフェースのみを公開しています。基礎となる表現は隠されていて(それは配列なのかリンクリストなのか?)、明確に定義されたインタフェースが提供されています。では、抽象化されたデータに誤ってアクセスしないようにするにはどうすればよいでしょうか。それがカプセル化が登場するところです。例えば、C++のクラスはアクセス指定子を使用して、偶然のアクセスと変更を確実に防止します。また、上記のインターフェイスをパブリックにすることで、スタックを操作する唯一の方法は、明確に定義されたインターフェイスを使用することです。その過程で、データとそれを操作できるコードを結合しました(ここではフレンド関数を使用しないでください)。つまり、コードとデータが一緒に結合されるか、結び付けられるかカプセル化されます。
抽象化---実装を隠す - 設計時---インタフェース/抽象クラスの使用
カプセル化 - データの非表示 - 開発 - アクセス修飾子の使用(パブリック/プライベート)
カプセル化はクラスである1つのカプセルの複雑さをまとめているため、カプセル化...抽象化は他のオブジェクトと区別するオブジェクトの特性ですが...
抽象化は、クラスabstractに1つ以上のメソッドabstractを持たせることで実現できます。これは、それを拡張したクラスによって実装されるべき特性に他なりません。例えばあなたが自動車を発明/設計するとき、あなたは自動車が4つのドア、ブレーキ、ハンドルなどを持っているべきであるように…あなたが誰もこの特性を含むべきであるのでこの特性を含むべきです。実装は抽象化のそれぞれの頭ではありません。含まれるべき特性を定義するだけです。
カプセル化は、パブリック、プライベート、継承、集約、または構成と共に保護されたアクセス修飾子を使用することによって、データと動作をクラスである1つのカプセルに保持することによって実現されます。ですから、あなたは必要なものだけを見せます。すなわち、公の、保護された、友好的な、そして私的な基本原則……。 GMは上記の抽象化されたデザインの自動車を使用することにしました。しかし、それらは同じ特性を持ち、ほぼ同じ機能を実行するさまざまな製品を持っています。そこで彼らは上記の抽象クラスを拡張するクラスを書きます。それはギアボックスがどのように働くべきであるか、ブレーキがどのように働くべきであるか、ハンドルがどのように働くべきであるかを言います。それからすべてのプロダクトはちょうどこの共通の機能性を使用する。彼らは、ギアボックスがどのように機能するか、機能を壊すか、ステアリングホイールが機能するかを知る必要はありません。個々の製品は確かに/ cやオートロックなどのようなより多くの機能を持つことができます…..
どちらも強力です。しかし抽象化を使用することはカプセル化よりも多くのスキルを必要とし、より大きなアプリケーション/製品は抽象化なしでは生き残れません。
私は簡単な方法でカプセル化を実証しようとします。
カプセル化は -
カプセル化は抽象化を実装します。
そして抽象化は -
例を見てみましょう -
以下の画像は、「データベースに追加される顧客の詳細」のGUIを示しています。
画像を見れば、カスタマークラスが必要だと言えます。
ステップ-1:私のカスタマークラスには何が必要ですか?
すなわち.
1顧客コードと顧客名をデータベースに追加する機能。
namespace CustomerContent {パブリッククラスCustomer {パブリック文字列CustomerCode = "";パブリック文字列CustomerName = ""; public void ADD(){//私のDBコードはここに行きます}
今ではADDメソッドだけがここで一人では動作しません。
ステップ-2:バリデーション、ADD機能はどのように機能しますか?
データベース接続コードと検証コード(追加のメソッド)が必要になります。
public bool Validate()
{
//Granular Customer Code and Name
return true;
}
public bool CreateDBObject()
{
//DB Connection Code
return true;
}
class Program
{
static void main(String[] args)
{
CustomerComponent.Customer obj = new CustomerComponent.Customer;
obj.CustomerCode = "s001";
obj.CustomerName = "Mac";
obj.Validate();
obj.CreateDBObject();
obj.ADD();
}
}
これで、追加のメソッド(Validate(); CreateDBObject()[複雑で追加のメソッド])をエンドユーザーに表示する必要がなくなりました。レコード..エンドユーザーは、データをデータベースに追加する方法を気にしません。
ステップ-3:エンドユーザーとのやり取りを含まない、余分で複雑な方法を非公開にする。
そのため、それらのComplicatedメソッドとExtraメソッドをプライベートにする代わりにパブリックにして(つまり、それらのメソッドを非表示にして)、obj.Validate()を削除します。 obj.CreateDBObject();メインクラスのプログラムから我々はカプセル化を達成する。
言い換えれば、エンドユーザーへのインターフェースの単純化はカプセル化です。
だから今、コードは以下のようになります -
namespace CustomerContent
{
public class Customer
{
public string CustomerCode = "";
public string CustomerName = "";
public void ADD()
{
//my DB code will go here
}
private bool Validate()
{
//Granular Customer Code and Name
return true;
}
private bool CreateDBObject()
{
//DB Connection Code
return true;
}
class Program
{
static void main(String[] args)
{
CustomerComponent.Customer obj = new CustomerComponent.Customer;
obj.CustomerCode = "s001";
obj.CustomerName = "Mac";
obj.ADD();
}
}
要約:
ステップ-1:私のカスタマークラスには何が必要ですか?抽象化です。
ステップ-3:ステップ-3:エンドユーザーの対話を含まない余分で複雑な方法をプライベートにするのはカプセル化です。
P.S - 上のコードは難しくて速いです。
から こちら
OOPSにおけるカプセル化と抽象化の違い
抽象化とカプセル化は、2つの重要なオブジェクト指向プログラミング(OOPS)の概念です。カプセル化と抽象化はどちらも相互に関連する用語です。
カプセル化と抽象化の実際の違い
カプセル化することは隠すことを意味します。カプセル化は、データ隠蔽とも呼ばれます。カプセル化は、内部に薬を隠すカプセル(薬の錠剤)のように考えることができます。カプセル化はラッピングで、単にプロパティとメソッドを隠しています。カプセル化は、コードとデータを1つのユニットに隠してデータを世界から保護するために使用されます。クラスはカプセル化の最も良い例です。
抽象化とは、意図したユーザーに必要な詳細のみを表示することです。その名のとおり、抽象化は「抽象的なもの」です。抽象クラスを作るためにプログラミング言語の抽象化を使います。抽象クラスは、クラスのメソッドとプロパティの抽象ビューを表します。
カプセル化と抽象化の実装上の違い
抽象化はインターフェイスと抽象クラスを使用して実装され、カプセル化はプライベートおよび保護されたアクセス修飾子を使用して実装されます。
OOPSは、プログラマが意図しない方法でデータにアクセスするのを防ぐことで、型の整合性を強化する(つまり、データが適切な方法で使用されるようにする)ためにカプセル化を利用します。カプセル化によって、所定の機能グループのみがデータにアクセスできます。アクセス制限(public/privateなど)と一緒にまとめられたデータ型と操作(メソッド)の総称はクラスです。
以下の段落は、それらが互いにどう違うのかを理解するのに役立ちました。
データのカプセル化はデータをバンドルするメカニズムであり、それらを使用する関数とデータの抽象化はインターフェイスのみを公開し、実装の詳細をユーザーから隠すメカニズムです。
もっと読むことができます ここ 。
情報の隠蔽は、抽象化やカプセル化に厳密には必要ありません。情報は無視されるかもしれませんが、隠される必要はありません。
カプセル化は、多くの複雑な部分やアイデアで構成されている場合でも、1つのものとして扱うことができます。 たとえば、私は椅子の中に座っているのではなく、その椅子のさまざまな部分のそれぞれが特定のデザインと機能を持っているのではなく、すべて快適に保持するためにぴったり合っていると言えます床から数フィート離れたところに私のお尻。
抽象化はカプセル化によって有効になります。私たちはオブジェクトをカプセル化しているので、内部オブジェクト構造の細部に悩まされるのではなく、何らかの方法で互いに関連するものとしてそれらを考えることができます。 抽象とは、全体像を考える能力であり、細部にわたって心配する必要はありません。学術論文の冒頭にある要約のように、言葉の根本は抽象的です。派生サブクラスとしてのみインスタンス化できるクラスのように抽象ではありません。
私は正直に言うと、私が自分の椅子に腰を下ろしたとき、その椅子の構造がどのようにして私の体重を支えているのかについて考えることはありません。それは私がそれらの詳細について心配する必要がないというまともな十分な椅子です。だから私は自分のコンピュータに注意を向けることができる。繰り返しますが、私は自分のコンピュータの構成要素については考えていません。私が入力できるテキスト領域を表すWebページの一部を見ているだけです。言葉でコミュニケーションを取っているだけで、指でキーボード上の正しい文字がすぐに見つけられる方法、そしてどのようにして正しいのかこれらのキーをタップすることとこのフォーラムに投稿することとの間で最終的に接続が確立されます。これが抽象化の大きな力です。システムの下位レベルは一貫性と正確性をもって動作すると信頼される可能性があるので、より大きな作業のために予備に注意を払います。
class Aeroplane : IFlyable, IFuelable, IMachine
{ // Aeroplane's Design says:
// Aeroplane is a flying object
// Aeroplane can be fueled
// Aeroplane is a Machine
}
// But the code related to Pilot, or Driver of Aeroplane is not bothered
// about Machine or Fuel. Hence,
// pilot code:
IFlyable flyingObj = new Aeroplane();
flyingObj.Fly();
// fighter Pilot related code
IFlyable flyingObj2 = new FighterAeroplane();
flyingObj2.Fly();
// UFO related code
IFlyable ufoObj = new UFO();
ufoObj.Fly();
// **All the 3 Above codes are genaralized using IFlyable,
// Interface Abstraction**
// Fly related code knows how to fly, irrespective of the type of
// flying object they are.
// Similarly, Fuel related code:
// Fueling an Aeroplane
IFuelable fuelableObj = new Aeroplane();
fuelableObj.FillFuel();
// Fueling a Car
IFuelable fuelableObj2 = new Car(); // class Car : IFuelable { }
fuelableObj2.FillFuel();
// ** Fueling code does not need know what kind of vehicle it is, so far
// as it can Fill Fuel**
抽象化は有用でないデータをユーザから隠しており、カプセル化はデータを1つのカプセル(クラス)にまとめます。カプセル化は抽象化を実現する方法だと思います。
抽象化とカプセル化の両方のプロセスでインタフェースが生成されます
カプセル化によって生成されたインタフェースは、実装の詳細を隠します。
抽象化によって生成されたインタフェースは、抽象化前と比較して、より多くのデータ型に適用可能になります。
Abstraction
は、これから実行しようとしている実装に対する規約です。実装は時が経つにつれて変わる可能性があります。さまざまな実装自体が隠されている場合もあれば隠されていない場合もありますが、抽象化の背後にあるマスクです。
あるクラスのすべてのAPIs
をinterface
に定義してから、コードのユーザーにAPIs
の定義済みのinterface
に依存するように依頼するとします。設定された契約に従う必要がある場合にのみ、実装の改善や修正を自由に行うことができます。ユーザーは私たちの実装と結合していません。
抽象化ですべての必要なルール(メソッド)を公開します。ルールの実装は実装者エンティティのために残されています、また実装はの一部ではありません抽象化です。その抽象シグネチャと宣言だけが抽象化を作ります。
Encapsulation
は単純に状態や動作へのアクセスを減らして内部の詳細を隠すです。カプセル化されたクラスは、よく定義されたAbstraction
を持っているかもしれません。
Java.util.List
はJava.util.ArrayList
の抽象概念です。 Java.util.ArrayList
アクセス修飾子でマークされているnon public
の内部状態はカプセル化です。
EditクラスContainer.nava implements IContainer
、IContainer
がaddElement
、removeElements
、contains
などのようなメソッドを宣言できると仮定します。ここでIContainer
はその実装クラスの抽象を表します。抽象化とは、クラスやモジュール、システムのAPIを外部に宣言することです。これらのAPIはcontract
になります。そのシステムはまだ開発されているかもしれませんし、されていないかもしれません。システムのユーザーは宣言されたAPIに依存することができ、そのような契約を実装するシステムは宣言されたAPIを常に遵守し、それらのAPIの実装を常に提供します。いったん具体的な実体を書いたら、次に内部状態を隠すことを決定するのがカプセル化です。
私は抽象化とカプセル化の間にここで線を引くことを試みる、私によると抽象化はカプセル化が抽象化の実装の1つであるより概念的なものです。カプセル化せずにデータを隠すことができるので、たとえばプライベート定数や変数を使用します。そのため、データ隠蔽によるカプセル化が可能ですが、データ隠蔽は必ずしもカプセル化ではありません。以下のコードでは、これらの概念のうち最も単純な形式を描いています。
// Abstraction
interface IOperation
{
int SquareNumber();
}
public class Operation
{
// Data hiding
private int number;
public Operation(int _number)
{
this.number = _number;
}
// Encapsulation
public int SquareNumber()
{
return number * number;
}
}
実際には、
IOperation obj = new Operation(2);
// obj.number <--- can't access because hidden from world using private access modifier but not encapsulated.
obj.SquareNumber(); // cannot access internal logic to calculate square because logic is hidden using encapsulation.
要するに
抽象化使用 - >カプセル化&カプセル化使用 - >データ隠蔽
OR
データ隠蔽はカプセル化およびのサブセットですカプセル化は抽象化のサブセットです
カプセル化は抽象化を実装する方法だと思います。次のリンクを見てください。
抽象化とカプセル化はどちらもデータ隠蔽のために知られています。しかし、大きな違いがあります。
カプセル化
カプセル化とは、データとそのデータを処理するコードをClassという単一の単位にバインドまたはラップするプロセスです。
カプセル化は、実装レベルで問題を解決します。
クラスでは、プライベートまたは保護されたアクセス修飾子を使ってデータを隠すことができます。
抽象化
抽象化は、無関係な詳細を隠すという概念です。言い換えれば、不必要な詳細をユーザから隠すことによって複雑なシステムを単純にします。
抽象化は、設計レベルで問題を解決します。
Javaでインタフェースと抽象クラスを作成することによって抽象化を達成できます。
Rubyでは、モジュールを作成することによって抽象化を達成できます。
例:私たちはRubyのArrayとHashでEnumerableモジュールの(collect、map、reduce、sort ...)メソッドを使います。
簡単なコード例でこれを試してみましょう
抽象=データ隠蔽+カプセル化
// Abstraction
interface IOperation
{
int GetSumOfNumbers();
}
internal class OperationEven : IOperation
{
// data hiding
private IEnumerable<int> numbers;
public OperationEven(IEnumerable<int> numbers)
{
this.numbers = numbers;
}
// Encapsulation
public int GetSumOfNumbers()
{
return this.numbers.Where(i => i % 2 == 0).Sum();
}
}
要するに:
抽象化は、どの特定の情報が重要でどの情報を隠すべきかを特定するのに役立つ手法です。
カプセル化は、オブジェクトの詳細や実装の詳細を隠すように情報を囲むための手法です。
抽象化
抽象化は、すべての既存および将来の実装の共通のプロパティとフィールドを抽出するプロセスです。
例えば、Carは、Sedan、Hatchback、SUV、Coupe、Convertibleを抽象化したものです。 Carはすべてのタイプの車に共通のすべてのプロパティとフィールドを持ちます。
カプセル化
カプセル化は、ユーザーから不要な詳細を隠すプロセスです。この用語はカプセルから来ています。薬がカプセルの内側に隠されているように。ミキサー、自転車、洗濯機、ラジオ、テレビから飛行機まで、さまざまな機械や設備、機器の詳細。あなたはマシンのすべての詳細がユーザーに見えるようにしたくありません。
プログラミング用語では:クラスCarを考えてみましょう。以下の例では、ユーザーが知る必要があるのはキーを回すこと(turnKey()メソッド)だけですが、内部関数については知りません。ユーザーは、内部機能や内部コンポーネントについて知る必要はありません。
この場合、すべてのプライベートメソッドは内部関数であり、 'Piston p1'のようなプライベートフィールドはユーザーが知る必要のない内部データです。
public class Car{
private void startMotor(){ //do something }
private void generateVoltage(){ //do something }
private void sparkPlugIgnition(){ //do something }
private void fuelFlowFromTankToInjector(){ //do something }
private void pushPistonsDown() {
p1.doAction();
p2.doAction();
//do something }
private void moveCrankShaft(){ //do something }
private Piston p1;
private Piston p2;
public void turnKey(){
startMotor();
generateVoltage();
sparkPlugIgnition();
fuelFlowFromTankToInjector();
pushPistonsDown();
moveCrankShat();
...
}
}