Encapsulation (computer programming)

 

  • この記事は、コンピュータサイエンスに関する技術および英語についての正確な知識のない翻訳者が個人的な勉強を目的として、ほぼ全てを意訳によって翻訳したために、極めて多くの誤訳が含まれていると想定される決して質が高いとは言えない文章を公開しているものです。ここに掲載されている情報を使用したことによる、読者の方または第三者に生じる損害および損失について、翻訳者は一切の責任を負いません。正しい情報が必要な場合は原文を参照してください。

 

オブジェクト指向プログラミング言語では、カプセル化は関連しているがいかに述べる異なる2つもののうちの一つを指すために通常は使われて、時々2つの組み合わせを指する。

  • オブジェクトの構成物のいくつかへの直接的なアクセスの制限のための言語メカニズム[3][4]
  • データを操作するメソッド(や他の関数)をもったデータを束ねることを簡単にする言語の構成物[5][6]

プログラミング言語の研究者やアカデミックの人の一部は最初の意味だけかオブジェクト指向プログラミングの特徴をはっきりさせるように二つ目の意味の組み合わせで使うが、語彙クロージャーを提供するいくつかのプログラミング言語ではカプセル化オブジェクト指向と直交する言語の特徴として見られる。

2つ目の定義の同期は多くのオブジェクト指向言語コンポーネントの隠蔽が自動的に行われずまたオーバーライドされうる事実が動機にある。このように、情報隠蔽は2つ目の定義を好む人々によって別の概念として定義される。

カプセル化の特徴はほとんどのオブジェクト指向言語ではクラスをつかうことでサポートされるが、他の手段もまた存在する。

 一般的な定義

カプセル化オブジェクト指向プログラミングの基礎の一つである。これはデータとそれを操作するメソッドの集まりを指す。カプセル化はクラス内の構造化されたデータオブジェクトの値と状態を隠すこと、つまり許可されていないところからそれらに直接アクセスさせないことに使われる。publicにアクセスできるメソッドは通常はクラスの中で提供されて(いわゆるgetterとsetterによって)値にアクセスする。また他のクライエントクラスがこれらのメソッドを使ってオブジェクト内の値を取り出したり修正したりする。

この機構はオブジェクト指向プログラミング固有のものではない。モジュールのような抽象データ型の実装で似たようなカプセル化ができる。こうした類似点はどちらの考えも数学的な基礎の実存型によるということに由来する。

情報隠蔽カニズム

カプセル化はデータメンバと関数メンバを隠すために使われうる。この定義の上では、カプセル化が意味することは、オブジェクトの内部表現がオブジェクトの定義の外からみれば、一般的に隠されているということだ。一般的に、オブジェクトが所有するメソッドのみが直接オブジェクトのフィールドを検知して操作することができる。SmalltalkRubyといった一部の言語ではオブジェクトのメソッドを通じてのみアクセスすることが許されているが、ほとんどの他の言語(例えばC++, C#, Delphi, Java)では、一般的にpublicやprivateといったキーワードで隠されているものをある程度操作することをプログラマーに許可している。ISO C++ Standardではprotected, private, publicを「アクセス修飾子」としている。また、これらは「すべての情報を隠」さないとしている。情報隠蔽はヘッダーファイルが境界となるコンパイル済のソースコードを供給することで達成される。

オブジェクトの内部を隠すことはユーザーがコンポーネントの内部データを無効な/矛盾するデータを設定することを防ぐことでオブジェクトの完全性を保護する。カプセル化で得られるだろう利益としては、開発者がソフトウェアコンポーネント間の内部依存性を制限できるため、システムの複雑性を軽減して、堅牢性を向上させ、ることが挙げられる。

ほとんど常に、そのような保護をオーバーライドする方法がある。通常は、リフレクションAPI(Ruby, Java, C#など)、時々は名前修飾のようなメカニズム(Python), また、C++におけるfliedのような特別なキーワードの用法などである。

カプセル化オブジェクト指向言語でなくても可能である。例えばCでは、構造体はpublicAPI(例えばヘッダーファイル)でAPIのクライエントがアクセスできないデータメンバを含むデータのアイテムを操作する関数の集まりのために宣言されている。

クライエントはAPI関数をつかって不透明データ型のオブジェクトのアロケーションをする。このタイプのコンテンツはAPI関数の実装にのみ知られアクセルされる。クライエントはそのコンテンツに直接アクセスできない。これらの関数のソースコードはストラクチャーの実際のコンテンツを定義する。

カプセル化と継承

Design Patternsの著者は継承とカプセル化の間の緊張について長々と議論して、経験的に設計者は継承を使いすぎると主張している。危険性が次のように主張されている:

継承はサブクラスに親クラスの実装の詳細をさらすので、しばしば「継承はカプセル化を破壊する」といわれる。- Gang of Four, Design Patterns (Chapter 1)