セッターって何?
前回はゲッターでprivateなフィールドの値を取り出しました。今回はprivateなフィールドである名前をクラスの外から変更するためのセッターを作ります。
ゲッターのおさらい
前回に続いて、お馴染みのHumanクラスを使います。
Human.java
public class Human{
private static int count_Human = 0;
String name;
int birthday;
int manpukudo;
Human(String name, int birthday, int manpukudo){ // コンストラクタ1
this.name = name;
this.birthday = birthday;
this.manpukudo = manpukudo;
count_Human++;
}
Human(String name, int birthday){ // コンストラクタ2
this(name, birthday, 50);
}
Human(){ // コンストラクタ3
this("不明", 0, 50);
}
public static int getCount_Human(){
return count_Human;
}
void eat(){
this.manpukudo += 60;
}
}御覧のように、このHumanクラスには4つのフィールド(メンバ変数)があります。以下の4つです。
Human.java
private static int count_Human = 0;
String name;
int birthday;
int manpukudo;ゲッターのおさらいも兼ねてHumanクラスのインスタンスフィールドであるnameをprivateにしましょう。
Human.java
public class Human{
private static int count_Human = 0;
private String name;
int birthday;
int manpukudo;
// 以下省略
}privateなフィールドにすることで、他のクラスから以下のように値を直接取得できなくなります(コンパイルエラーになります)。
HumanTest.java
Human human1 = new Human();
System.out.println(human1.name);Humanクラスの内部ではprivateなフィールドにもアクセスできるので、外部から名前を取得するようのメソッドであるゲッターを作りましょう。
Human.java
public class Human{
private static int count_Human = 0;
private String name;
int birthday;
int manpukudo;
// コンストラクタ省略
public String getName(){
return this.name;
}
}取得したいフィールドの値をreturnするだけのメソッドです。今回は外部に公開するためpublicにします。このように値を取得するメソッドをゲッターと呼ぶんでした。名前は各インスタンスのデータなので、getName()にはstaticを付けません。
ゲッターを他のクラスから呼ぶことで戻り値としてそのインスタンスが持つフィールドの値をゲットできます。
HumanTest.java
Human human1 = new Human();
System.out.println(human1.getName());こんな感じです。
セッターとは
ゲッターを利用することで、privateなフィールドの値をゲットできるようになりました。しかし、ゲッターはその名の通りフィールドの値をゲットするだけです。そのフィールドの値を書き換えることはできません。
今度はprivateなフィールドを書き換えるためのメソッド、セッターを作ります。
セッターを作る前に、まずセッターをどんな風に使うかを説明します。例えば、1977年1月1日生まれの「ノブオ」という名前のオブジェクトを作って、
HumanTest.java
public class HumanTest{
public static void main(String[] args){
Human human1 = new Human("ノブオ",19770101);
}
}「ノブオ」を「ノブ」に改名するとします。つまり、human1のインスタンスフィールドnameの値を「ノブオ」から「ノブ」に書き換えます。
HumanTest.java
public class HumanTest{
public static void main(String[] args){
Human human1 = new Human("ノブオ",19770101);
human1.setName("ノブ");
}
}このように、setName()の引数にセットしたい値を放り込むわけです(「set」と「get」を見間違わないように注意)。
セッターの名前は、「set + 書き換えたいフィールド名(頭文字は大文字)」とするのが普通です。とは言っても、ただのメソッド名なのでどんな名前でも大丈夫です。とは言っても、メソッド名を見ることで、そのメソッドの役割が分かるようにしておくのは重要なことです。
では、上記のように引数を受け取ってその値をフィールドにぶち込むセッターをHumanクラスのpublicなメンバとして作りましょう。(あえて先に使い方を説明しましたが、もちろん定義するからこそ使えます。)
Human.java
public class Human{
private static int count_Human = 0;
private String name;
int birthday;
int manpukudo;
// コンストラクタ省略
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
}( )の中に仮引数を宣言してString型の値を受け取れるようにしています。そして、その受け取った値を、自身のインスタンスフィールドのname(this.name)に代入しています。これがセッターです。
このセッターは値を返さないので戻り値の型はvoidです。右辺のnameは仮引数、左辺のthis.nameはこのインスタンスのフィールドを指します。
セッターの応用
セッターは値を設定するためのメソッドなわけですが、受け取った値をそのままフィールドに代入するだけでなく、代入する前にその値が不正な値ではないかチェックするような機能を持たせることもできます。
例えば、「名前」は10文字以内というルールを設定したとしましょう。受け取ったStringが10文字を超えた場合はフィールドに放り込まずにエラーメッセージが出るようにします。
Human.java
public class Human{
// 関係ないところは省略してます
private String name;
public void setName(String name){
if(name != null && name.length() <= 10){
System.out.println(this.name + "を" + name + "に変更しました");
this.name = name;
}else{
System.out.println("名前はnullではなく、10文字までにしてください");
}
}
}length()はStringの長さを返すメソッドです。例えば、nameが「ノブオ」ならname.length()は3になります。今回はこの値で10文字以内かを判断します。
厳密にはlength()が数えるのはUTF-16のコード単位なので、一部の漢字や絵文字などでは見た目の文字数と一致しません。ここでは、例に使うカタカナなどで考えてください。
条件のname != nullは、nullに対してlength()を呼ばないためのチェックです。&&は左側がfalseなら右側を評価しません。
ちょっと脱線しましたが、要はsetNameメソッドに、引数に受け取った文字列が10文字以内かどうかをチェックする機能を付け加えたわけです。実際、使ってみましょう。
HumanTest.java
public class HumanTest{
public static void main(String[] args){
Human human1 = new Human("ノブオ",19770101);
human1.setName("アヤノコウジ ノブゴロウ");
human1.setName("ノブ");
System.out.println(human1.getName());
}
}HumanTestのmainメソッドを実行すると、結果はコンソールに表示されます。
名前はnullではなく、10文字までにしてください
ノブオをノブに変更しました
ノブこの例は名前を変更するときのチェックです。作成時にも同じルールを守らせるには、コンストラクタ側にも入力チェックが必要です。
このように、セッターというのは、引数に与えられた値をそのままフィールドに代入するだけではなく、その値が正しい値かどうか?つまりその値をフィールドに代入することで何か不具合が起きたりバグの原因になったりしないかをチェックする機能を持たせることも可能です。
ゲッターとセッターが理解できたら、次回は「カプセル化」について説明します。
質問・コメント
読み込み中この記事についての質問や、学習して気づいたことをお寄せください。
この記事のコメント
旧サイトに寄せられたコメントも当時の投稿内容のまま掲載しています。現在の記事では変更している内容や、旧環境についてのやり取りも含まれます。
コメントを読み込んでいます。