カプセル化とは、オブジェクトの中身を外部に対して非公開にすることです。
と言っても、よく分からないと思うので、実際にコードも見ながら解説していきます。
カプセル化の書き方
カプセル化の書き方としては、変数やメソッドを定義する際に、初めにprivateという修飾詞をつけるだけです
private データ型 変数名;
private データ型 メソッド名;
//変数例
private String name;
private int age;
//メソッド例
private int getName(){ return name; }
private void setAge(int a){ age = a; }
privateがついた変数やメソッドは、同じクラス内でしか参照することができなくなります。
カプセル化のメリット
カプセル化のメリットは以下の2つです。
・変数の影響範囲を狭める
・間違った値の代入や変更を防ぐ
実際に例を用いて説明していきましょう。
変数の影響範囲を狭める
社員の名前と年齢を管理するemployeeクラスがあったとします。
employeeクラスをTestクラスで呼び出して、社員の年齢を表示します。
カプセル化していないコード
カプセル化したコード
employeeクラス
class employee{
//名前
String name = "山田太郎";
//年齢
int age = 25;
Testクラス
class Test{
public static void main(String args[]){
//employeeオブジェクト作成
employee emp = new employee();
//empオブジェクトのメンバ変数ageを直接呼び出す
System.out.println(emp.age);
}
employeeクラス
class employee{
//名前
private String name = "山田太郎";
//年齢
private int age = 25;
//名前を取得するメソッド
public String getName(){
return name;
}
//年齢を取得するメソッド
public int getAge(){
return age;
}
}
Testクラス
class Test{
public static void main(String args[]){
//employeeオブジェクト作成
employee emp = new employee();
//カプセル化するとこれはできない
//System.out.println(emp.age);
//publicなgetAgeメソッドを呼び出す
System.out.println(emp.getAge());
}
}
カプセル化していないコードでは、メンバ変数ageを直接呼び出して年齢を表示しています。
それに対し、カプセル化しているコードでは、メンバ変数ageを直接呼び出すことができないため、他クラスからでも呼び出せるgetAgeメソッドを使ってメンバ変数ageを呼び出しています。
ここで、年齢を生年月日から求めることに変わりました。
その時の変更箇所を見てみましょう。
カプセル化していないコード
カプセル化したコード
employeeクラス
class employee{
//名前
String name = "山田太郎";
//誕生日
Date birthday;
}
Testクラス
class Test{
public static void main(String args[]){
//employeeオブジェクト作成
employee emp = new employee();
//年齢の表示
Date date = emp.birthday;
【年齢の計算処理】
System.out.println(【計算結果】);
}
}
employeeクラス
class employee{
//名前
private String name = "山田太郎";
//誕生日
private Date birthday;
//名前を取得するメソッド
public String getName(){
return name;
}
//年齢を取得するメソッド
public int getAge(){
【年齢の計算処理】
return 【計算結果】;
}
}
Testクラス
class Test{
public static void main(String args[]){
//employeeオブジェクト作成
employee emp = new employee();
//年齢の表示
System.out.println(emp.getAge());
}
}
カプセル化したコードでは、employeeクラスを利用する側(Testクラス)のコードの変更箇所が多くなっています。
カプセル化していないコードでは、employeeクラスのコードを変更するだけで、利用する側のコードに変化はありません。
この例では、employeeクラスを利用している箇所が1箇所だけなので、変更するのに大した労力はいりません。
しかし、これが100箇所で利用していたらどうでしょう?
1つ1つ直していくのは相当大変です。
変数の影響範囲を狭めておくことで、仕様が変わった時の修正箇所を少なくすることができるのです。
間違った値の代入や変更を防ぐ
同様に、employeeクラスの例で見てみましょう。
Testクラスからemployeeクラスの年齢を変更することにしました。
それぞれ年齢(age)に、年齢としてはあり得ない値(-100)で更新してみます。
カプセル化していないコード
カプセル化したコード
employeeクラス
class employee{
//名前
String name = "山田太郎";
//年齢
int age = 25;
Testクラス
class Test{
public static void main(String args[]){
//employeeオブジェクト作成
employee emp = new employee();
//年齢-100歳というありえない値が代入されてしまう
emp.age = -100;
}
employeeクラス
class employee{
//名前
private String name = "山田太郎";
//年齢
private int age = 25;
//名前を更新するメソッド
public void setName(String n){
name = n;
}
//年齢を更新するメソッド
public void setAge(int a){
if(a < 0){
System.out.println("値が正しくないよ");
}else{
age = a;
}
}
}
Testクラス
class Test{
public static void main(String args[]){
//employeeオブジェクト作成
employee emp = new employee();
//「値が正しくないよ」が出力される
emp.setAge(-100);
//メンバ変数ageが20に更新される
emp.setAge(20);
}
}
カプセル化したコードでは年齢(age)に-100というあり得ない値を代入しようとすると、「値が正しくないよ」と出力するようにメソッドを定義しました。
こうすることで、年齢(age)に不正な値が代入されることを不正でいます。
一方、カプセル化していないコードでは、年齢(age)に不正な値(-100)を代入しても、問題なく処理されます。
このように、カプセル化することで変数への不正な値の代入を防ぎます。
まとめ
・カプセル化の書き方
private データ型 変数(メソッド)名
・カプセル化のメリット
- 仕様変更時の修正箇所を少なくできる
- 不正な値の代入を防ぐ
コメント