オブジェクト指向の基本原則である「カプセル化」についての理解を”なんとなく”ではなく”しっかり”理解するためのシンプルな備忘録。ここではJavaを用いて説明する。
カプセル化の基本理解
ざっくり言うと 「①関係性のあるデータをまとめて、②外部から隠すこと」 である。
これによって、ソフトウェアの更新の際にどこをいじればいいのかが明確になり、不用意な更新を防ぐことができる。
①関係性のあるデータをまとめる
関係するフィールドやメソッドをひとまとめにすることで、関係性のないデータをクラスから取り除くことができる。これにより、このクラスはこの役割を果たすんだな、とクラスの目的が明確になる。
では、”ひとまとめにする”とはどういうことなのか?
例えば、クラスAとクラスBがあったとする。クラスAのメソッドがBのフィールドにアクセスできる場合は、ひとまとめにされていないと言える。AのメソッドからBのフィールドにアクセスできるのであれば、AのメソッドはBにあるべきだからだ。
②外部から隠す(データ隠蔽)
値の書き換えを防ぐにはアクセス制限をかける必要がある。
アクセス制限をかけるには、アクセス修飾子を用いる。
アクセス修飾子は以下の3種類があり、各役割は以下の通り。
アクセス修飾子 | 役割 |
---|---|
public | すべてのクラスからアクセス可能 |
protected | 同じパッケージに属する or 継承しているサブクラスからのみアクセス可能 |
private | 同じクラス内からのみアクセス可能 |
以上の①②を踏まえて、カプセル化はどのように実装するのか?
Javaを用いた例を挙げる。
カプセル化の実現
Javaでカプセル化を実現するには、
⑴ フィールドは非公開にする
⑵ フィールドを使ったメソッドは公開する
これだけで良い。
なぜなら、フィールドの公開はせず、メソッドを通してのみフィールドへアクセスする形にすれば良いからだ。
フィールドへのアクセスが可能となると意図せず値が更新されてしまう可能性があるので、フィールドは非公開にしなければいけない。
しかし、メソッドも非公開にすると他のクラスから何も操作できない状態となってしまうので、メソッドは公開にする必要がある。
そして、⑴ ⑵ は上の表を参考に以下のようなアクセス修飾子をつければ実現する。
⑴ フィールドの非公開 → private
⑵ フィールドを使ったメソッドの公開 → public
ここで1点注意すべきなのが、すべてのメソッドを公開にする必要はなく、必要なものだけで良いと言うことだ。
Javaのコード例を挙げると以下の通り。
public class Hoge {
private int num; //フィールドは非公開に
public int getNum() { return num; } //フィールドの値を得るだけなので公開で良い
private void setNum(int num) { this.num = num; } //フィールドの値を操作するので非公開に
}
どのメソッドを公開・非公開にするべきなのかしっかり見極めることがカプセル化の実装において重要なのだと思った。