カプセル化とは?

Java

カプセル化とは、オブジェクトの中身を外部に対して非公開にすることです。

と言っても、よく分からないと思うので、実際にコードも見ながら解説していきます。

カプセル化の書き方

カプセル化の書き方としては、変数やメソッドを定義する際に、初めに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 データ型 変数(メソッド)名

・カプセル化のメリット
 - 仕様変更時の修正箇所を少なくできる
 - 不正な値の代入を防ぐ

コメント

タイトルとURLをコピーしました