追記:2020/3/13 今回の内容は、「カプセル化」というより「データ隠蔽」の内容になっていたことをコメントで指摘していただいたので、修正。
タイトルもカプセル化からデータ隠蔽へ変更。
#はじめに
この記事は備忘録である。
参考書レベルの内容だが、本記事に掲載するコードについては、
間違えたものが中心となる。これは実際にコーディング中に間違えた部分を掲載し、自分で反省するために投稿するという目的によるもの。
また、後日にJavaSilver試験問題の勉強を兼ねて復習するため、深い部分の話はここでは触れない。
##環境
言語:Java11、JDK13.0.2
動作環境:Windows10
#メンバへのアクセス制限
new
で生成したインスタンスが、クラスから引き継いだメンバ(フィールドとメソッド)を独自の形で保有していることは確認した。だが、前回のCat
クラスで言えば
Cat myCat = new Cat;
mycat.weight = -20;
と、Cat
クラスを作ったときには想定していなかった値を、main
メソッド内から勝手に格納することが出来てしまう。
main
メソッド内から直接、Cat
クラスで設定された**フィールド(今回はdouble weight
)**にアクセスを許していると問題を起こしかねない。
##private
そこで、「クラス処理の外部からは扱うことが出来ないメンバ(フィールド・メソッド)を持たせたい」場合に、メンバ(フィールド・メソッド)へつける修飾子が**private
**である。
今回はString型のcolorから、double型のheight(身長)へ変更して、Catクラスを扱ってみたい。
class Cat
{
private double weight;
private double height;
//クラス
public void setWeightHeight(double w,double h)
{
if(w > 0 && w <= 50){
weight = w;
System.out.println("この猫の体重を" + weight + "kgにしました。");
} else{
System.out.println("ちょっとこの体重はないんじゃないですかねぇ……");
}
if(h > 0 && h <= 200){
height = h;
System.out.println("この猫の身長を" + height + "cmにしました。");
} else{
System.out.println("流石にそんな身長の猫は聞いたことはない……");
}
}
double getWeight()
{
System.out.println("猫の体重を更新します。");
return weight;
}
double getHeight()
{
System.out.println("猫の身長を更新します。");
return height;
}
void introduce()
{
System.out.println("この猫の体重は" + weight + "kgです。");
System.out.println("この猫の身長は" + height + "cmです。");
}
}
Catクラスのweight height
はいずれもprivate
になったので、勝手に値をいじられる心配は無くなった。
##public
だが本当に値を変更できないのであれば、新しくnew
したいmyCat
インスタンスの値も変えることが出来ない。
しかし、Cat
クラスで言えば
public void setWeightHeight(double w,double h)
に注目してもらいたい。これはCatクラスに定義したメソッドだが、その修飾子は**public
**に設定されている。これは「クラスの外側からのアクセスを許す」修飾子であり、処理の中に
weight = w;
height = h;
と、private
に設定したフィールドにアクセスしている。
メソッドのうち、同じクラスの中に入っているメソッドからであればprivate
へのアクセスが可能であることを利用し、メソッド内処理経由でprivate
に設定した値への格納は許されている。
public void setWeightHeight(double w,double h)
はその内部にif文を抱えており、条件に合わない値の代入を阻止できるようになっている。これでとんでもない値を格納される心配はなくなった。
#終わりに
今回見た、「メソッドを使ってprivate
フィールドへ値を格納する」という処理について。参考書のやさしいJava 第7版から引用すると、
クラスの中にデータ(フィールド)と機能(メソッド)をひとまとめにし、保護したいメンバにprivateをつけて勝手にアクセスできなくする機能
である。この機能設計を
~~カプセル化(encapsulation)~~データ隠蔽
と呼んでいる。
これはオブジェクト指向設計の基本的な原則のひとつであり、このためにクラスを作るのである。他の原則はまた扱うがどれも大切な原則なので、しっかり把握しておきたい。
#参考
出来るだけ自分で変数や式を書いてコンパイルしているので、完全に引用する場合はその旨記述する。