カプセル化
カプセル化とは?
オブジェクト指向の3大特徴のうちの1つ、カプセル化の解説をしていきたいと思います。
カプセル化とは、「外から見て複雑でない状態を作ること」です。言葉を変えると、「抽象化する」ということです。物事を抽象化すると、わかりやすくなります。
もうちょっと具体的に言うと、「クラスの内部構造を隠蔽すること」をカプセル化と言います。
- クラスのフィールドを隠蔽
フィールドを隠すと、他のクラスから直接アクセスできないようになります。これにより、不適切な値の設定ができなくなります。
例えば、Personクラスのオブジェクトの「ageフィールドに200歳やマイナスの値を設定する」などです。
- 代わりのメソッドを用意する
- ゲッター
- フィールドから値を取得する
- セッター
- フィールドに値を設定する
フィールドを完全に隠蔽してしまうと何もできなくなってしまうので、メソッドを介してフィールドにアクセスさせるようにします。メソッドにすることにより入力チェックの処理などを実装できるので、不適切な値を設定するのを防ぐことができます。
このようなメソッドをアクセッサメソッド、と言います。
フィールドの隠蔽
- privateという修飾子をつける
名前と年齢というフィールドを持っているPersonクラスを例にします。
Personを使う側のクラスは、フィールドに直接アクセスすることができなくなります。
アクセッサメソッドの作成
フィールドへのアクセスを可能にするために、代わりのメソッド(アクセッサメソッド)を用意します。アクセッサメソッドは2種類あります。
- getter
- フィールドの値を取得するメソッド
メソッド名は「get」から始まります。の部分にはフィールド名を指定します。先頭の文字は大文字にします。
Personクラスのnameフィールドのゲッターです。
人の名前を返すので戻り値の型はとします。nameフィールドと同じデータ型になります。
メソッド名はとします。の部分はフィールド名で先頭の文字が大文字になっていることに注意しましょう。メソッドの中身は、最もシンプルな処理の場合「フィールドnameの値をreturnする」となります。
- setter
- 値をフィールドにセットするメソッド
戻り値は必要ありませんので、voidとします。メソッド名は「set」から始まります。の部分にはフィールド名を指定します。先頭の文字はゲッターの時と同様、大文字にします。
Personクラスのageフィールドのセッターです。
戻り値の型は、メソッド名はとします。の部分はフィールド名で先頭のアルファベットは大文字になります。
引数のデータ型は年齢が入ってくるためint型にします。ageフィールドと同じデータ型です。
メソッドの中身は、引数の名前をとしたので、このクラスのフィールドに代入するためにというキーワードを使用します。「このクラスのフィールドである」ということを示しています。
thisキーワード
thisキーワードとは?自分自身を指す特別なキーワードのことです。
このクラスのフィールドであることを示しています。コンストラクタやsetterなどでよく使用されます。以下はsetterのサンプルですが、
ageを代入する先のフィールドはとなっています。
このクラスのコンストラクタを呼び出します。コンストラクタが複数ある場合、一方のコンストラクタからもう一方のコンストラクタを呼び出す時などに使います。
Employeeクラスでは、引数2つのコンストラクタから、引数1つのコンストラクタを呼び出すところで指定しています。
フィールドに引数の値を代入するところで、場合によっては入力チェックなども行うことがあるでしょう。引数1つのコンストラクタの方に実装しておき、を使って呼び出せば、チェック処理を入れる箇所は1箇所で済みます。
まとめると
カプセル化について少しモヤッとする方もいるのではないでしょうか?
- フィールドをprivateにしてもsetterを用意したら同じことでは?
- 年齢の入力チェックは可能でも名前のチェックは難しいのでは?
「カプセル化」とは?ある種のお作法のようなものと捉えてもよろしいかと思います。
使い所
- データを一時的に保存する場合
- 単体の値ではなく複数の値を一まとめにする場合(JavaBeans)
Personクラスをカプセル化すると、以下のようになります。