web-dev-qa-db-ja.com

抽象化とカプセル化の違いは?

インタビューの準備をしていて、OOPの概念を磨くことにしました。数百の記事が利用可能ですが、それぞれが異なる説明をしているようです。 一部 は言う

抽象化とは、「体系的なバリエーションを持つ一般的なパターンを識別するプロセスです。抽象化は、一般的なパターンを表し、使用するバリエーションを指定する手段を提供します」(リチャードガブリエル)。

そして、抽象クラスを通じて達成されます。

一部 other

抽象化は、オブジェクトのクライアントに必要な詳細のみを表示することを意味します

そして

Employeeクラスにメソッド "CalculateSalary"があり、EmployeeIdをパラメーターとして受け取り、今月の従業員の給与を整数値として返すとします。誰かがそのメソッドを使用したい場合。彼は、Employeeオブジェクトが給与を計算する方法を気にする必要はありませんか?彼が心配する必要がある唯一のことは、メソッドの名前、その入力パラメーター、および結果のメンバーの形式、

私は何度も何度もグーグルで検索しましたが、どの結果も適切な答えを与えてくれなかったようです。 さて、カプセル化はこれらすべてにどこに適合しますか?私は検索し、 stack overflow question を見つけました。その質問への答えでさえ混乱を招きました ここ 、それは言います

カプセル化は、抽象化の一部として使用される戦略です。カプセル化はオブジェクトの状態を指します-オブジェクトは状態をカプセル化し、外部から隠します。クラスの外部ユーザーはそのメソッドを介してクラスとやり取りしますが、クラスの状態に直接アクセスすることはできません。そのため、クラスはその状態に関連する実装の詳細を抽象化します。

ここ 別の評判の良いメンバーは言う、

それらは異なる概念です。

抽象化とは、オブジェクトの不要/重要でない属性をすべて整理し、ドメインに最適な特性のみを保持するプロセスです。

今、私は全体の概念を台無しにしています。抽象クラス、継承、アクセス指定子などすべてについて知っています。私はただ知りたいインタビューで抽象化やカプセル化について尋ねられたとき、どのように答えるべきですか?

重複としてマークしないでください。同様の質問がいくつかあります。しかし、私は矛盾する説明の間の混乱を避けたいです。誰もが信頼できるリンクを提案できますか? stackoverflowの質問へのリンクも、混乱を引き起こさない限り歓迎します。 :)

編集:私は答えが必要です、少しc#指向です

65
Aparan

抽象化は、オブジェクトのクライアントに必要な詳細のみを表示することを意味します

実際にはカプセル化です。カプセル化とデータの隠蔽によって混乱しないように、ウィキペディアの記事の最初の部分も参照してください。 http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)

クラスメンバーをプロパティの背後に1対1で非表示にするだけでは、カプセル化されないことに注意してください。カプセル化とは、不変式を保護し、実装の詳細を隠すことです。

ここでそれについての良い記事。 http://blog.ploeh.dk/2012/11/27/Encapsulationofproperties/ は、その記事にリンクされている記事もご覧ください。

クラス、プロパティ、およびアクセス修飾子は、c#でカプセル化を提供するツールです。

複雑さを軽減するためにカプセル化を行います。

抽象化とは、「体系的なバリエーションを持つ一般的なパターンを識別するプロセスです。抽象化は、一般的なパターンを表し、使用するバリエーションを指定する手段を提供します」(リチャードガブリエル)。

はい、それは抽象化の良い定義です。

それらは異なる概念です。抽象化とは、オブジェクトの不要/重要でない属性をすべて整理し、ドメインに最適な特性のみを保持するプロセスです。

はい、それらは異なる概念です。実際には、抽象化はオブジェクトをあなたのドメインのみに適したものにすることの反対であることに留意してください。オブジェクトを一般的なドメインに適したものにするためです!

実際の問題があり、特定のソリューションを提供している場合、抽象化を使用して、同じ一般的なパターンを持つより多くの問題を解決できるより一般的なソリューションを形式化できます。そうすれば、コンポーネントの再利用性を高めたり、同じドメインまたは異なるドメイン用に作成された他のプログラマーが作成したコンポーネントを使用したりできます。

良い例は、リストやコレクションなど、.netフレームワークによって提供されるクラスです。これらは非常に抽象的なクラスであり、ほぼどこでも多くのドメインで使用できます。 .netが、特定のプロパティを持つ従業員と会社のリストのみを保持できるEmployeeListクラスとCompanyListのみを実装すると想像してください。そのようなクラスは多くの場合役に立たないでしょう。また、たとえばCarListの機能全体を再実装しなければならないとしたら、どんな苦痛でしょう。そのため、「リスト」は従業員、会社、および自動車から離れています。リスト自体は、独自のクラスで実装できる抽象概念です。

インターフェイス、抽象クラス、または継承とポリモーフィズムは、c#で抽象化を提供するツールです。

再利用性を提供するために抽象化を行います。

48
Egi

カプセル化:ゲッターやセッターなどを使用してデータを非表示にします。

抽象化:抽象クラスやインターフェースなどを使用して実装を非表示にします。

94
Bunny

Abstraction & Encapsulation Example 画像ソース

抽象:は、猫の左上と右上の画像で輪郭が描かれています。外科医と老婦人は異なる方法で動物を設計(または視覚化)しました。同様に、アプリケーションのニーズに応じて、Catクラスに異なる機能を配置します。すべての猫には肝臓、膀胱、心臓、肺がありますが、猫を「ゴロゴロ」だけさせる必要がある場合は、アプリケーションの猫を右上ではなく左上のデザインに抽象化します。

カプセル化:は、テーブルの上に立っている猫によって概説されています。それは、猫の外の誰もが猫をと見るべきものです。猫の実際の実装が左上のものか、右上のものか、あるいは両方の組み合わせであるかを心配する必要はありません。


PS:Go here この上完全な話を聞くための同じ質問。

45
displayName

カプセル化と抽象化を簡単な方法で実証しようとします。

  • データと関数を単一のユニット(クラスと呼ばれる)にまとめることをカプセル化と呼びます。内部データ構造やコードなど、オブジェクトに関する情報を格納および非表示にするカプセル化。

カプセル化は-

  • 複雑さを隠す、
  • データと関数を結合し、
  • 複雑なメソッドをプライベートにする、
  • インスタンス変数をプライベートにする、
  • 不要なデータと機能をエンドユーザーから隠す。

カプセル化は抽象化を実装します。

そして抽象化は-

  • 必要なものを示す、
  • データはエンドユーザーから抽象化する必要があり、

例を見てみましょう

以下の画像は、「データベースに追加される顧客の詳細」のGUIを示しています。

Customer Screen GUI

画像を見ると、顧客クラスが必要であると言えます。

ステップ-1:私の顧客クラスには何が必要ですか?

つまり.

  • 顧客コードと顧客名を保存する2つの変数。

  • 1顧客コードと顧客名をデータベースに追加する機能。

  namespace CustomerContent
    {
       public class Customer
       {
           public string CustomerCode = "";
           public string CustomerName = "";
           public void ADD()
           {
              //my DB code will go here
           }

ここでは、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() [複雑で追加のメソッド])をエンドユーザーに表示する必要はありません。エンドユーザーは、顧客コード、顧客名、およびADDを参照して知るだけです。レコードを追加するボタン。エンドユーザーは、データベースにデータを追加する方法を気にしませんか?.

ステップ-3:エンドユーザーの操作を必要としない余分で複雑なメソッドをプライベートにします。

したがって、それらの複雑で余分なメソッドをパブリックではなくプライベートにして(つまり、これらのメソッドを非表示にし)、クラスProgramのメインから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:顧客クラスには何が必要ですか? isAbstraction.

ステップ-3:ステップ-3:エンドユーザーの操作を必要としない余分で複雑なメソッドをプライベートにしますカプセル化

PS -上記のコードはハードで高速です

更新:このリンクにサンプルを説明するビデオがあります: 抽象化とカプセル化の違いは何ですか

25
Sanchit

それらはわずかに異なる概念であると思いますが、しばしば一緒に適用されます。カプセル化は、呼び出し元から実装の詳細を隠すための手法です。一方、抽象化は、理解を助けるために、使い慣れたオブジェクト/プロセスに類似したオブジェクトの作成を含む設計哲学です。カプセル化は、抽象化の作成に使用できる多くの手法の1つにすぎません。

たとえば、「windows」を使用します。それらは伝統的な意味での実際のウィンドウではなく、画面上の単なるグラフィカルな正方形です。しかし、それらをウィンドウと考えると便利です。それは抽象化です。

「windows API」がテキストまたはグラフィックスがウィンドウの境界内で物理的にレンダリングされる方法の詳細を隠す場合、それはカプセル化です。

9
Mike Panter

オブジェクト指向分析と設計(OOAD)は、実際には4つの原則に基づいています。彼らです:

  • Abstraction:は、設計に必要なエンティティの機能のみを組み込むことを意味します。したがって、すべての銀行口座に開設日があり、アプリケーションが口座の開設日を知る必要がない場合、BankAccountのオブジェクト指向設計にOpeningDateフィールドを追加するだけではありません。クラス。 OOADの抽象化は、プログラミングの抽象クラスとは何の関係もありません。この原則により、エンティティは実際のabstractionです。銀行口座の抽象化は、アプリケーションが必要とするその詳細レベルまで設計します。

  • 継承:は実際の原則よりもtrickに似ており、作成した機能を書き直す必要がありません。何処か別の場所。唯一のことは、あなたが書いている新しいコードと再利用したい古いコードの間に関係がなければならないということです。 inherit両親の富と同じように、inherit親クラスのフィールドとメソッドです。そのため、親クラスのすべてを取得し、必要に応じてさらに追加するのが継承です。オブジェクト指向デザインで継承を探しに行かないでください。継承が現れます。

  • 多態性:は継承の結果です。親からメソッドを継承することは便利ですが、状況に応じてメソッドを変更できることは多態性です。サブクラスにメソッドを実装するには、親クラスと同じように完全に同じ署名を使用します。これにより、呼び出されたときに子クラスのメソッドが実行されます。これがポリモーフィズムです。

  • カプセル化:は、関連する機能をまとめて、onlyにアクセスする必要があることを意味します。この原則は、オブジェクト指向設計でのクラス設計の基礎です。ここで:

    • 関連するデータとメソッドを組み合わせます。そして、
    • すべてのデータとメソッドが公開されているわけではありません。

別の簡略化された答えは here です。


「OOADの抽象化はOOPの抽象キーワードになる」と主張する人々...正しくない

例:オブジェクト指向の原則を使用してアプリケーションで大学を設計する場合、大学の「抽象化」のみを設計します。通常、ほとんどすべての大学に1つのATMがありますが、アプリケーションに必要ない場合は、その事実を組み込むことはできません。そして今、あなたは大学の抽象化だけを設計しましたが、あなたは置く必要はありません abstract クラス宣言で。大学の抽象的なデザインは、アプリケーションの通常のクラスになります。

6
displayName

私の2c

カプセル化の目的は、クラスのユーザーから実装の詳細を隠すことです。クラス内の項目のstd :: listを内部的に保持し、std :: vectorの方が効果的であると判断した場合、ユーザーが気にせずにこれを変更できます。つまり、いずれかのstlコンテナと対話する方法は抽象化のおかげです。たとえば、リストとベクトルの両方を、同様のメソッド(イテレータ)を使用して同じ方法で走査できます。

4
Anders

抽象化のコンテキストで、常に1つの例が提示されています。自動車の自動変速機対手動変速機。手動変速機は、ギアを変更する機能の一部を隠しますが、ドライバーとしてクラッチとシフトをする必要があります。自動変速機は、ギアの変更の詳細をすべてカプセル化します。つまり、それをユーザーから隠します。したがって、ギアを変更するプロセスのより高い抽象化です。

3
Lorentz Vedeler

カプセル化:実装の詳細(注:データAND/ORメソッド)を非表示にして、外部から感知できるほど読み取り可能/書き込み可能/使用可能なもののみにアクセスできるようにします。

抽象化:これは、インスタンス化できないタイプを明確に指す場合があり、通常はサブクラス化によって他のタイプのテンプレートを提供します。より一般的には、「抽象化」とは、詳細度が低く、具体性が低く、粒状性の低いものを作成/所有することを指します。

いくつかの類似性、概念間の重複がありますが、それを覚える最良の方法は次のとおりです。カプセル化は非表示詳細であり、抽象化は一般化詳細です。

1
Brad Thomas

抽象化とカプセル化はわかりにくい用語であり、互いに依存しています。例で見てみましょう。

public class Person
    {
        private int Id { get; set; }
        private string Name { get; set; }
        private string CustomName()
        {
            return "Name:- " + Name + " and Id is:- " + Id;
        }
    }

Personクラスを作成したら、プロパティと関数(Id、Name、CustomName)を一緒に記述してカプセル化を行いました。このクラスをクライアントに公開するときに抽象化を実行します

Person p = new Person();
p.CustomName();

クライアントは、この関数のIdとNameについて何も知りません。ここで、クライアントは関数呼び出しを邪魔することなく姓も知りたい場合。このようにPersonクラスにもう1つのプロパティを追加して、カプセル化を行います。

public class Person
        {
            private int Id { get; set; }
            private string Name { get; set; }
            private string LastName {get; set;}
            public string CustomName()
            {
                return "Name:- " + Name + " and Id is:- " + Id + "last name:- " + LastName;
            }
        }

見てください、クラスに追加のプロパティを追加した後でも、クライアントはあなたがコードに何をしたかを知りません。ここで抽象化を行いました。

1
CredibleAshok

抽象化

Javaでは、抽象化とは、情報を現実世界に隠すことを意味します。 「サービスを利用するために何をすべきか」を伝えるために、当事者間の契約を確立します。

例、API開発では、実際の実装ではなく、サービスの抽象化された情報のみが世界に公開されています。 Javaのインターフェースは、この概念を非常にうまく実現するのに役立ちます。

インターフェースは、生産者と消費者などの当事者間の契約を提供します。生産者は、製品の製造方法を消費者に知らせることなく商品を生産します。しかし、インターフェースを介して、Producerはすべての消費者にどの製品を購入できるかを知らせます。抽象化の助けを借りて、生産者は消費者に製品を販売できます。

カプセル化:

カプセル化は抽象化の1レベル下です。同じ製品会社は、お互いの生産グループから情報を保護しようとします。たとえば、会社がワインとチョコレートを生産している場合、カプセル化は、各製品が互いにどのように製造されているかを示す情報の保護に役立ちます。

  1. ワイン用とチョコレート用に個別のパッケージがあり、すべてのクラスがデフォルトのアクセス修飾子としてパッケージで宣言されている場合、すべてのクラスに対してパッケージレベルのカプセル化を行います。
  2. パッケージ内で、各クラス(メンバーフィールド)をprivateとして宣言し、それらのフィールドにアクセスするためのパブリックメソッドを持っている場合、この方法でそれらのフィールドにクラスレベルのカプセル化を提供します
0
Shaan

このように考えると、カプセル化は何かが行われる方法を隠しています。これは、1つまたは複数のアクションにすることができます。

抽象化は、最初にカプセル化する「理由」に関連しています。

私は基本的にクライアントに次のように伝えています。「支払いの処理方法や配送料の計算方法などについて詳しく知る必要はありません。 」

このように、Checkoutリクエストに一般化(抽象化)することで詳細をカプセル化しました。

私は本当に抽象化とカプセル化がうまくいくと思います。

0
FrankO

私が知っているように、カプセル化はクラス自体のデータを隠し、外界からアクセスする必要がある場合にのみセッター/ゲッターを介してアクセスできるようにします。

抽象化は、それ自体のクラス設計です。

手段、クラスツリーの作成方法、メソッドは一般的なもの、継承されるもの、オーバーライド可能なもの、属性はプライベートレベルのみ、または保護されているもの、クラス継承ツリーを構築する方法、finalを使用する方法クラス、抽象クラス、インターフェース実装。

抽象化はoo-designフェーズに配置され、カプセル化は開発フェーズにも登録されます。

0
icbytes