オブジェクト指向の抽象化は、クラス レベルの設計中に発生します。これは、ある意味で、基になる実装にアクセスするための「インターフェイス」を簡素化するという意味で、API / デザイン / システムによって提供される機能がどのように実装されたかという実装の複雑さを隠すことを目的としています。
抽象化のプロセスは、クラスの「より高い」レベル (レイヤー) で繰り返すことができます。これにより、コードの複雑さと各レイヤーでの理解を増やすことなく、大規模なシステムを構築できます。
たとえば、Java 開発者はFileInputStreamの機能を気にせずに高レベルの機能を利用できます (つまり、ファイル ハンドル、ファイル システムのセキュリティ チェック、メモリ割り当て、およびバッファリングは内部で管理され、コンシューマには隠されます)。これにより、 の実装をFileInputStream
変更できます。また、API (インターフェース) が一貫している限り、FileInputStream
以前のバージョンに対してビルドされたコードは引き続き機能します。
同様に、独自のクラスを設計するときは、内部の実装の詳細をできるだけ隠したいと思うでしょう。
Booch の定義1では、 OO カプセル化はInformation Hidingによって実現されます。具体的には、クラス インスタンスが所有する内部データ (状態を表すフィールド/メンバー) を非表示にすることで、制御された方法で内部データへのアクセスを強制し、直接、これらのフィールドへの外部変更、およびクラスの内部実装メソッドを非表示にします (たとえば、それらを非公開にすることによって)。
たとえば、クラスのフィールドはprivate
デフォルトで作成でき、これらへの外部アクセスが必要な場合にのみ、get()
および/またはset()
(またはProperty
) がクラスから公開されます。(現代の OO 言語では、フィールドをreadonly
/ final
/としてマークすることができますimmutable
。これにより、クラス内であっても変更がさらに制限されます)。
情報隠蔽が適用されていない例 (Bad Practice) :
class Foo {
// BAD - NOT Encapsulated - code external to the class can change this field directly
// Class Foo has no control over the range of values which could be set.
public int notEncapsulated;
}
フィールドのカプセル化が適用された例:
class Bar {
// Improvement - access restricted only to this class
private int encapsulatedPercentageField;
// The state of Bar (and its fields) can now be changed in a controlled manner
public void setEncapsulatedField(int percentageValue) {
if (percentageValue >= 0 && percentageValue <= 100) {
encapsulatedPercentageField = percentageValue;
}
// else throw ... out of range
}
}
フィールドの不変/コンストラクターのみの初期化の例:
class Baz {
private final int immutableField;
public void Baz(int onlyValue) {
// ... As above, can also check that onlyValue is valid
immutableField = onlyValue;
}
// Further change of `immutableField` outside of the constructor is NOT permitted, even within the same class
}
Re : 抽象化 vs 抽象クラス
抽象クラスは、クラス間の共通性の再利用を促進するクラスですが、それ自体を直接インスタンス化することはできません。new()
抽象クラスはサブクラス化する必要があり、concrete
(非抽象) サブクラスのみをインスタンス化できます。おそらく、Abstraction
と の間の混同の原因の 1 つabstract class
は、オブジェクト指向の初期の頃、コードの再利用を実現するために継承がより頻繁に使用されていたことです (たとえば、関連付けられた抽象基本クラス)。今日では、構成は一般に継承よりも好まれており、インターフェース、イベント/デリゲート/関数、トレイト/ミックスインなどを介して抽象化を実現するために利用できるツールが増えています.
Re : カプセル化 vs 情報隠蔽
カプセル化の意味は時間の経過とともに進化したようで、最近では、どのメソッド、フィールド、プロパティ、イベントなどをクラスにバンドルencapsulation
するかを決定する際に、より一般的な意味で一般的に使用することもできます。
ウィキペディアを引用:
オブジェクト指向プログラミング言語のより具体的な設定では、この概念は、情報隠蔽メカニズム、バンドルメカニズム、またはこの 2 つの組み合わせのいずれかを意味するために使用されます。
たとえば、声明では
データ アクセス コードを独自のクラスにカプセル化しました。
..カプセル化の解釈は、懸念の分離または単一責任プリンシパル(SOLID の「S」)とほぼ同等であり、リファクタリングの同義語として使用できる可能性があります。
[1] Booch のカプセル化猫の写真を見たら、カプセル化を忘れることはできません - オブジェクト指向分析とアプリケーションによる設計、第 2 版の p46