カプセル化(コンピュータープログラミング)

ウィキペディアから、無料の百科事典
ナビゲーションにジャンプ 検索にジャンプ

オブジェクト指向プログラミング(OOP)では、カプセルとは、データを操作するメソッドとデータをバンドルすること、またはオブジェクトのコンポーネントの一部への直接アクセスを制限することを指します。[1]カプセル化は、クラス内の構造化データオブジェクトの値または状態を非表示にするために使用され、非表示の実装の詳細を公開したり、メソッドによって維持される状態の不変性に違反したりする可能性のある方法で、クライアントがそれらに直接アクセスするのを防ぎます。

公的にアクセス可能なメソッドは、通常、状態にアクセスしたり、状態をより抽象的に変更したりするためにクラスで提供されます。実際には、値に間接的にアクセスするためのメソッド(いわゆる「getters」および「setters」)が提供されることがありますが、必ずしも抽象的なカプセル化に違反しているわけではありませんが、オブジェクト指向プログラミングが不十分である可能性のある標識と見なされることがよくあります。 (OOP)設計プラクティス[2]アンチパターン)。

このメカニズムはOOPに固有のものではありません。モジュールなどの抽象データ型の実装は、同様の形式のカプセル化を提供します。類似性は、存在型の観点からプログラミング言語理論家によって説明されています。[3]

意味

オブジェクト指向プログラミング言語やその他の関連分野では、カプセル化とは、関連しているが異なる2つの概念の1つを指し、場合によってはそれらの組み合わせを指します。[ 4] [5]

一部のプログラミング言語の研究者や学者は、最初の意味を単独で、または2番目の意味と組み合わせて、オブジェクト指向プログラミングの際立った特徴として使用します。一方、字句クロージャを提供するプログラミング言語の中には、カプセル化をオブジェクト指向に 直交する言語の特徴と見なすものがあります。

2番目の定義は、多くのオブジェクト指向言語やその他の関連フィールドでは、コンポーネントが自動的に非表示にならず、これをオーバーライドできるという事実に基づいています。したがって、情報隠蔽は、2番目の定義を好む人々による別個の概念として定義されます。

カプセル化の機能は、ほとんどのオブジェクト指向言語の クラスを使用してサポートされていますが、他の選択肢もあります。

カプセル化と継承

デザインパターンの作成者は、継承とカプセル化の間の緊張関係について詳しく説明し、彼らの経験では、デザイナーは継承を使いすぎていると述べています。彼らは、継承がサブクラスをその親の実装の詳細に公開することを考えると、継承はしばしばカプセル化を破ると主張します。[9]ヨーヨー問題で説明されているように、継承の使いすぎ、つまりカプセル化は、複雑になりすぎてデバッグが困難になる可能性があります。

情報隠蔽

カプセル化は「データメンバーとメンバー関数を非表示にするために使用できる」という定義の下では、オブジェクトの内部表現通常、オブジェクトの定義の外部のビューから非表示になります。通常、オブジェクト自体のメソッドのみがそのフィールドを直接検査または操作できます。オブジェクトの内部を非表示にすると、ユーザーがコンポーネントの内部データを無効または一貫性のない状態に設定できないようにすることで、オブジェクトの整合性が保護されます。カプセル化の想定される利点は、開発者がソフトウェアコンポーネント間の相互依存性を制限できるようにすることで、システムの複雑さを軽減し、堅牢性を高めることができることです。[要出典]

SmalltalkRubyなどの一部の言語では、オブジェクトメソッドを介したアクセスのみが許可されていますが、他のほとんどの言語(C ++C#DelphiJavapublicなど)では、通常はやなどのキーワードを使用して、非表示にするものをある程度制御できprivateます。[7] ISO C ++標準はprotectedprivateおよびpublicを「アクセス指定子」と呼び、「情報を隠す」ことはありません。情報の隠蔽は、ヘッダーファイルを介してインターフェイスされるソースコードのコンパイル済みバージョンを提供することによって実現されます。

ほとんどの場合、このような保護をオーバーライドする方法があります。通常はリフレクションAPI(Ruby、Java、C#など)を介して、場合によっては名前マングリングPythonfriend )などのメカニズム、またはC ++などの特別なキーワードの使用によってです。オブジェクトレベルの機能ベースのセキュリティ(オブジェクト機能モデルに準拠)を提供するシステムは例外であり、強力なカプセル化を保証します。

データフィールドの制限

C ++C#JavaPHPSwiftDelphiなどの言語は、データフィールドへのアクセスを制限する方法を提供します。

以下は、キーワード を使用してデータフィールドへのアクセスを制限する方法を示すC#の例です。private

クラス プログラム
{
    パブリック クラス アカウント
    {
        プライベート 小数アカウント バランス =  500.00 m ;

        public  decimal  CheckBalance ()
        {これを
            返し ますaccountBalance ; 
        } 
    }

    static  void  Main ()
    {
        アカウント myAccount  = 新しい アカウント(); 
        10進数 のmyBalance  =  myAccount CheckBalance ();

        / *このMainメソッドは、パブリックを介して残高を確認できます
         *「Account」クラスによって提供される「CheckBalance」メソッド
         *ただし、「accountBalance」の値を操作することはできません* / 
    } 
}

以下はJavaの例です。

public  class  Employee  { 
    private  BigDecimal  salary  =  new  BigDecimal 50000.00 );
    
    public  BigDecimal  getSalary () {これを
        返し ます給与; 
    }

    public  static  void  main () {
        従業員 e  = 新しい 従業員(); 
        BigDecimal  sal  =  e getSalary (); 
    } 
}

非オブジェクト指向言語でもカプセル化が可能です。たとえば、 Cでは、externキーワードを使用してAPIのクライアントがアクセスできないデータメンバーを含むデータ項目を操作する一連の関数のヘッダーファイルを介して、パブリックAPIで構造を宣言できます。[10] [11]

//ヘッダーファイル "api.h"

struct  Entity ; //非表示のメンバーを持つ不透明な構造          

// 'Entity'オブジェクトを操作するAPI関数
externstruct Entity * open_entity int id ;      
extern int process_entity struct Entity * info );                 
extern void close_entity struct Entity * info );                
//ここでのexternキーワードは冗長ですが、害はありません。
// externは、現在のファイルの外部で呼び出すことができる関数を定義します。キーワードがなくてもデフォルトの動作です。

クライアントはAPI関数を呼び出して、不透明(OPAQUE)型のオブジェクトの割り当て、操作、および割り当て解除を行いますこのタイプのコンテンツは既知であり、API関数の実装にのみアクセスできます。クライアントはそのコンテンツに直接アクセスできません。これらの関数のソースコードは、構造の実際の内容を定義します。

//実装ファイル「api.c」

#include "api.h" 

struct  Entity { 
    int ent_id ; // ID番号charent_name [ 20 ] ; //名前...および他のメンバー..。              
           
        
};

// API関数
の実装structEntity  * open_entity int id    
{ ... }  

int process_entity struct Entity * info    
{ ... }  

void close_entity struct Entity * info    
{ ... }  

名前マングリング

以下は、変数アクセス制限をサポートしていないPythonの例です。ただし、慣例では、名前の前にアンダースコアが付いている変数はプライベートと見なす必要があります。[12]

class  Car  
    def  __init __ self  ->  None 
        self _maxspeed  =  200
 
    def  drive self  ->  None 
        print f "最大速度は{ self。_maxspeed } " 
 
redcar  =  Car ()
redcar drive ()  #これは「最大速度は200です」と出力します。

レッドカー_maxspeed  =  10redcar 
_ drive ()#これは「最大速度は10です」と出力します。  

も参照してください

参考文献

  1. ^ a b ロジャース、Wm。ポール(2001年5月18日)。「カプセル化は情報隠蔽ではありません」JavaWorld2020年7月20日取得
  2. ^ Holub、Allen(2003年9月5日)。「なぜゲッターとセッターのメソッドが悪かったのか」情報ワールドJavaWorld。2020-07-29にオリジナルからアーカイブされました2021年1月17日取得
  3. ^ Pierce 2002、§24.2存在するデータの抽象化
  4. ^ スコット、マイケル・リー(2006)。プログラミング言語の語用論(2版)。モーガンカウフマン。p。481. ISBN 978-0-12-633951-2カプセル化メカニズムにより、プログラマーはデータとそれらを操作するサブルーチンを1つの場所にグループ化し、抽象化のユーザーから無関係な詳細を隠すことができます。
  5. ^ デール、ネルB。; ウィームズ、チップ(2007)。Javaによるプログラミングと問題解決(第2版)。ジョーンズ&バートレット。p。396. ISBN 978-0-7637-3402-2
  6. ^ ミッチェル、ジョンC.(2003)。プログラミング言語の概念ケンブリッジ大学出版局。p。522. ISBN 978-0-521-78098-8
  7. ^ a b ピアス、ベンジャミン(2002)。タイプとプログラミング言語MITプレス。p。266. ISBN 978-0-262-16209-8
  8. ^ コノリー、トーマスM。; ベッグ、キャロリンE.(2005)。「第25章:オブジェクトDMBSの概要§オブジェクト指向の概念」。データベースシステム:設計、実装、および管理への実用的なアプローチ(第4版)。ピアソン教育。p。814. ISBN 978-0-321-21025-8
  9. ^ ガンマ、エーリヒ; ヘルム、リチャード; ジョンソン、ラルフ; ジョン・ブリシディーズ(1994)。デザインパターンアディソン-ウェスリー。ISBN 978-0-201-63361-0
  10. ^ キング、KN(2008)。Cプログラミング:最新のアプローチ(PDF)(第2版)。WWノートンアンドカンパニー。p。464. ISBN  978-03939795032019年11月1日取得
  11. ^ King、Kim N. Cプログラミング:現代的なアプローチWWノートン&カンパニー、2008年。Ch。18、p。464、 ISBN 0393979504 
  12. ^ バーダー、ダン。「Pythonでのアンダースコアの意味」Pythonスキルを向上させます2019年11月1日取得