カプセル化とは
データとメソッドを1つのオブジェクトにまとめてその内容を隠蔽すること!だそうです。
オブジェクト外から直接アクセスすることを出来なくして、不正なアクセス・意図しない変更から守ることができるのです!
オブジェクト指向の1種
オブジェクト指向の構成要素3つのうちの1つになるそうです。
構成要素は以下の3つです。
- 継承
- カプセル化
- ポリモーフィズム
カプセル化するには?
データを保護することがカプセル化です。
その保護をするために、アクセス修飾子と言うものを使ってアクセスを制限していきます。
アクセス修飾子
アクセス修飾子には制限の範囲に合わせて使うものが変わってきます。
以下が一覧になります。
私も使いこなせているわけではないですが。(privateしか使ったことありません)
カプセル化ではprivateを使用します。
- open モジュール外からもアクセスできる。
- public モジュール外からもアクセスできる。 サブクラス化されない。 overrideできない。
- internal モジュール内ならアクセスできる。 デフォルトでこれになっている。
- fileprivate ファイル内ならアクセスできる。
- private クラスなど宣言内でしかアクセスできない。(カプセル化に使用)
使ってみた
実際にカプセル化を学ぶきっかけになったコードになります。
tableViewを使用するアプリを作成していて、セルに表示する内容を書くコードだけ別のクラスに書くように指示がありました。
この場合、別のクラスでcheckIconやlabelを使用しようとすると、エラーになります。
class TableViewCell: UITableViewCell {
//privateを付けることで他のクラスからアクセスできない
@IBOutlet private var checkIcon: UIImageView!
@IBOutlet private var label: UILabel!
func configure(isChecked: Bool, name: String) {
//チェックされているときには表示して、チェックされていない時は表示しないという処理を書く
checkIcon.image = nil
if isChecked == true {
checkIcon.image = UIImage(named: "check")
}else{
checkIcon?.image = nil
}
label.text = name
}
}
カプセル化した値は外から変更できないのか?
結論:できます。
そもそもカプセル化とはデータを保護し、異常なデータ変更や意図しない変更を防ぐためにあります。
直接変更しなければ良いのです。
その方法は、関数を使うことです。
1度関数を通せば意図的な変更になりますし、異常な変更を加えるコードであっても、その変更に対応できるコードを関数内に書くことでエラーを防ぐことができるそうです。
カプセル化はオブジェクト指向
データを直接変更するのではなく(バグが発生する可能性があるため)、関数などのオブジェクト自体がデータの変更を行う。これがオブジェクト指向になります。
カプセル化はオブジェクト指向の重要な構成要素になります。
参考サイト
https://jpazamu.com/encapsulation/
https://dev.classmethod.jp/articles/swift3_scoped_access_level/