記事の書かれ方について
授業スライドとかを参考にしてるわけじゃないので、別の切り口から説明されてると思うけど。
たぶん言ってることはあっている(はず)。
アドリブなのでミスがあるかもしれないのであったら教えて!
4部構成です
Part.1 さっくりインスタンス生成をしてみる
Part.2 コンストラクタを使ってもっとすっきり
Part.3 アクセス制御をして、入ってくる値を制限しよう ←イマココ
Part.4 クラス変数・メソッドを使ってみる
つなぎ
Part.2 ではコンストラクタを実装した。
コンストラクタはインスタンスが生成されたときに一度だけ実行される特殊なメソッドのこと。
コンストラクタはクラスの名前を書いてやることで実装できる。
class DigitalStudentCard{
//学籍番号
int num;
//お名前
String name;
//コンストラクタ
DigitalStudentCard(int num, String name){
//引数のnumをインスタンスのnum(this.num)へ代入
this.num = num;
//同じく
this.name = name;
}
//出力する用のメソッド(自己紹介してもらう)
String getSelfIntroduction(){
return "学籍番号 : " + num + " 名前 : " + name);
}
}
コンストラクタの勝手はほぼメソッドと同じなので似たような感覚で書いていいと思う。
アクセス制限をしよう!
アクセス制限と聞くと、なんか縛りを設けるんやろなぁ...という感じがすると思う。そんな感じでおk。
private
やpublic
を付けてやることで変数やメソッド、コンストラクタに対してアクセスを制限することができるのです!!
こういうキーワードのことをアクセス修飾子なんて言ったりするけど
だいたいみんなは「privateにしたら?」とか「publicじゃないんじゃない?」とか言ったりしてます。
そんなアクセス修飾子の種類は以下の通り。
修飾子 | 効能 |
---|---|
public | どこからでもアクセスできる |
(何も書かない) | パッケージ内のどこからでもアクセスできる。(いつか説明する) |
protected |
extends やimplements による親子関係がある場合にのみアクセスできる。(いつか説明する) |
private | そのクラス、インスタンスからのみアクセスできる。 |
書いてみる
num
とname
にprivate
アクセス修飾子を付けてみよう。
class DigitalStudentCard{
//学籍番号
private int num;
//お名前
private String name;
//コンストラクタ
DigitalStudentCard(int num, String name){
//引数のnumをインスタンスのnum(this.num)へ代入
this.num = num;
//同じく
this.name = name;
}
//出力する用のメソッド(自己紹介してもらう)
String getSelfIntroduction(){
return "学籍番号 : " + num + " 名前 : " + name);
}
}
これを使うのを書く。
class UseClass{
public static void main(String[] args){
//インスタンス生成
DigitalStudentCardtanaka = new DigitalStudentCard(118114, "田中角栄");
//別のインスタンスを生成
DigitalStudentCardnoguchi = new DigitalStudentCard(118514, "野口英世");
//出力
System.out.println(tanaka.getSelfIntroduction);
// 学籍番号 : 118114 名前 : 田中角栄
System.out.println(noguchi.getSelfIntroduction);
// 学籍番号 : 118514 名前 : 野口英世
}
}
この例では何も変わらないけど、次のような書き方がNGとなる。
tanaka.num = 114514;
//コンパイルエラー
tanaka.name = "田中角栄";
//コンパイルエラー
num
とname
をインスタンス内部でないとアクセスできないようにprivate
アクセス修飾子で制限したのでこれらができなくなる。
なんでこんな面倒くさいことが必要なの?
「どっからでもアクセスできた方が便利だし、楽でいいじゃーん」
確かに、制約を設けない方が好きな書き方ができていいように思える。
けど、好き放題できるってヤバそうに聞こえない?
そう。ヤバいんですよ。(語彙が少ない)
これがマジモンの学生証だとしたら勝手に学籍番号とか名前を書き換えられちゃたまらないでしょう。
変えるにしても、番号とか名前とか、従ってほしいルールがあるはず。
そのようなルールを設けるためにゲッタ(Getter) / セッタ(Setter)と呼ばれるメソッドを実装しよう。
ゲッタ/セッタを作る
「こう呼ばれてる」ってだけで、別に特殊なメソッドの書き方をするってことではないので安心してほしい。
今までもよく見かけてきたああいう書き方でっせ。
ゲッタ/セッタはget〇〇()
、set〇〇()
と名付けるのが無難。
class DigitalStudentCard{
//学籍番号
private int num;
//お名前
private String name;
//コンストラクタ
DigitalStudentCard(int num, String name){
//せっかく作ったのでゲッタを使う
setNum(num);
//同じく
setName(name);
}
//出力する用のメソッド(自己紹介してもらう)
String getSelfIntroduction(){
return "学籍番号 : " + num + " 名前 : " + name);
}
// ----- 追加 -----
//numを返すだけのメソッド(ゲッタ)
int getNum(){
return num;
}
//nameを返すだけのメソッド(ゲッタ)
String getName(){
return name;
}
//numを設定するメソッド(セッタ)
void setNum(int number){
//うちの学校の学籍番号を例にして考えてみる
//何となく年っぽくなってるとこを抜き出す
int year = number/1000;
//119を超える値を禁止する
if(year > 118){
year = 118;
}
//番号っぽいとこだけ抜き出す
number = number%1000;
//3桁に収めたいので999を超える値は999にする
if(number > 999){
number = 999;
}
//くっつけて返す
return year*1000 + number;
}
//nameを設定するメソッド(セッタ)
void setName(String name){
this.name = name;
}
}
今度はこれらのメソッドを呼び出してみよう。
class UseClass{
public static void main(String[] args){
//インスタンス生成
DigitalStudentCardtanaka = new DigitalStudentCard(118114, "田中角栄");
//num変数の値を表示
System.out.println(tanaka.getNum());
// >> 118114
//name変数の値を表示
System.out.println(tanaka.getName());
// 田中角栄
//num変数の値を変更
tanaka.setNum(200, 1000);
// わざと大きい値を入れてみる
//name変数の値を変更
tanaka.setName("たなかかくえい");
// ネタが思い浮かばなかったのでとりまひらがなに
System.out.println(tanaka.getNum());
// 118999
System.out.println(tanaka.getName());
// たなかかくえい
}
}
こうしてやることで、nun
だけ欲しい!name
だけ欲しい!なんて時はgetNum()
やgetName()
を使うことで対応できる。
のっぴきならぬ事情で学籍番号変えたいな~とか、結婚して名字が変わったなんてときはsetNum()
やsetName()
を使って設定ができる。
学籍番号はメチャメチャな値を入れられたら困るので、適切な値であるかを確認する仕組みを作っている。
変数num
に入る値を限定できるので、無法地帯と化すことを避けられる。
コンストラクタでもsetNum()
、setName()
を使っているので代入処理を行っている部分を一か所だけにすることができた。
こうすることで後々、バグがあったとしても1箇所だけ確認すればいいので修正が楽になるんです!!
ちなみに
アクセス修飾子はメソッドや、コンストラクタにも用いることができる。
private void setName(String name){
//なんか処理
}
アクセスできる範囲は変数同様にそのクラス・インスタンス内のみに限定される。
次回
次はクラス変数、クラスメソッドを使っていろんな場所から同じオブジェクトにアクセスしてみよう!
つぎ → Part.4 クラス変数・メソッドを使ってみる