カプセル化
カプセル化とはオブジェクト内の細かい処理内容やデータ構造を外部から隠蔽することを言い、オブジェクト指向を構成するために非常に重要な概念となっています。
カプセル化はアクセス修飾子によってアクセス制限をかけることで実現させます。
下記にサンプルを記します。
アクセス修飾子には以下のような種類があります。
public 全てのクラスからアクセス可能
protected サブクラスおよび同じパッケージからのクラスからのみアクセス可能
修飾子なし 同じパッケージのクラスからのみアクセス可能
private 同じクラスからのみアクセス可能
上記例は前回の記事で作成したCarクラスに走行距離という概念を取り入れたものです。
車が走った距離を示す走行距離は、当然走るごとに増えていき、減ることはありえません。
CarクラスにupdSokokyoriメソッドを定義し、updSokokyoriメソッドでは引数で受け取った走行距離分を総走行距離に足し合わせる処理を行っています。
引数でマイナスの数値を受け取った場合は何もしません。
しかし、次の行でCarクラスのフィールドであるインスタンス変数sokokyoriに対してCarクラスの呼び出し元クラスから直接減算しています。
走行距離が減るということはありえませんので、この処理はCarクラスが持つ論理に反してしまっています。
このように呼び出し元クラスがCarクラスに対して論理に反するようなことができてしまうのは非常に問題です。
そこでCarクラスをカプセル化することにより、呼び出し元クラスがCarクラスに対して好き勝手できないように制限をかけてやるのです。
上記サンプルをコンパイルすると「sokokyoriはCarでprivateアクセスされます。」とコンパイラがエラーを返すと思います。
これはCarクラスのフィールド全てにprivateアクセス修飾子を付加したことにより、アクセス制限をかけたためです。
誤りが起きにくいプログラムを作成するためにはカプセル化の概念は絶対おさえておかなければなりません。
アクセス修飾子はフィールド以外にもクラスそのものやメソッドにもつけることができます。
実際に色々試して、それぞれの違いを把握してください。
カプセル化はアクセス修飾子によってアクセス制限をかけることで実現させます。
下記にサンプルを記します。
public class AccSample{
public static void main(String[] args){
Car car;
car = new Car("インサイト", 24, 1339, 1000);
car.updSokokyori(100);
car.sokokyori -= 100;
System.out.println("走行距離 : " + car.getSokokyori());
}
}
class Car{
String name;
int nenpi;
int haikiryo;
int sokokyori;
Car(String n, int ne, int ha, int so){
name = n;
nenpi = ne;
haikiryo = ha;
sokokyori = so;
}
String getName(){
return name;
}
void updSokokyori(int kyori){
if(kyori > 0){
sokokyori += kyori;
}
}
int getSokokyori(){
return sokokyori;
}
int getNenpi(){
return nenpi;
}
int getHaikiryo(){
return haikiryo;
}
}アクセス修飾子には以下のような種類があります。
public 全てのクラスからアクセス可能
protected サブクラスおよび同じパッケージからのクラスからのみアクセス可能
修飾子なし 同じパッケージのクラスからのみアクセス可能
private 同じクラスからのみアクセス可能
上記例は前回の記事で作成したCarクラスに走行距離という概念を取り入れたものです。
車が走った距離を示す走行距離は、当然走るごとに増えていき、減ることはありえません。
car.updSokokyori(100);
car.sokokyori -= 100;
CarクラスにupdSokokyoriメソッドを定義し、updSokokyoriメソッドでは引数で受け取った走行距離分を総走行距離に足し合わせる処理を行っています。
引数でマイナスの数値を受け取った場合は何もしません。
しかし、次の行でCarクラスのフィールドであるインスタンス変数sokokyoriに対してCarクラスの呼び出し元クラスから直接減算しています。
走行距離が減るということはありえませんので、この処理はCarクラスが持つ論理に反してしまっています。
このように呼び出し元クラスがCarクラスに対して論理に反するようなことができてしまうのは非常に問題です。
そこでCarクラスをカプセル化することにより、呼び出し元クラスがCarクラスに対して好き勝手できないように制限をかけてやるのです。
public classAccSample{
public static void main(String[] args){
Car car;
car = new Car("インサイト", 24, 1339, 1000);
car.updSokokyori(100);
car.sokokyori -= 100;
System.out.println("走行距離 : " + car.getSokokyori());
}
}
class Car{
private String name;
private int nenpi;
private int haikiryo;
private int sokokyori;
Car(String n, int ne, int ha, int so){
name = n;
nenpi = ne;
haikiryo = ha;
sokokyori = so;
}
String getName(){
return name;
}
void updSokokyori(int kyori){
if(kyori > 0){
sokokyori += kyori;
}
}
int getSokokyori(){
return sokokyori;
}
int getNenpi(){
return nenpi;
}
int getHaikiryo(){
return haikiryo;
}
}上記サンプルをコンパイルすると「sokokyoriはCarでprivateアクセスされます。」とコンパイラがエラーを返すと思います。
これはCarクラスのフィールド全てにprivateアクセス修飾子を付加したことにより、アクセス制限をかけたためです。
誤りが起きにくいプログラムを作成するためにはカプセル化の概念は絶対おさえておかなければなりません。
アクセス修飾子はフィールド以外にもクラスそのものやメソッドにもつけることができます。
実際に色々試して、それぞれの違いを把握してください。
