こんにちは!リンコですピヨ!この記事では自分の勉強の復習もかねて、Kotlinでのゲッターとセッターについて詳しく解説するピヨ!
この第18章では、プログラミング言語であるKotlinのゲッターとセッターについて、一緒に勉強していきましょう。
この記事を読めばプログラミング未経験の方も、Kotlin入門レベルのゲッターとセッターについて1つ1つ理解しながら勉強できると思うので、是非最後まで読んで頂ければと思います。
※この記事で出てくる「サンプルコード」は、記述が長く画面からはみ出ている場合がありますが、横にスライドすると表示されるのでご安心ください。
【Kotlin】ゲッターとセッターとは?
ではまず、ゲッターとセッターとは何か?を勉強していきましょう。
ゲッターとセッターの書式
まずは、さっそくゲッターとセッターの書式を見てみます。
var 変数名 = "" get() { return field } set(value) { field = value }
ゲッターについて
まずゲッターは、クラスのインスタンス内に蓄えてある値をゲットするための関数です。
セッターについて
セッターはインスタンスのプロパティに値をセットするための関数です。
基本的に自動で動いてくれる見えない関数
このゲッターとセッターは、基本的には裏側で自動で動いてくれる見えない関数です。
このような、クラス内の特定の変数に値をセットしたり、変数の値を参照したりする関数を「アクセサ」と呼びます。
ゲッターとセッターは自分で書き換えることもできる
ただ、基本的には見えない関数ですが、自分で記述して書き換えることもできます。
ゲッターとセッターを自分で記述する場面は、後程紹介していきます。
ゲッターとセッターはアクセサと言って、裏側で自動で動いてくれる見えない関数ピヨ!
【Kotlin】自動で動いているゲッターとセッターのコードを見てみよう
ゲッターとセッターについて少しでも理解したところで、裏側で自動で動いているゲッターとセッターのコードを見てみましょう。
ゲッターとセッターが見えていない状態のコード
同じ内容のコードですがコードを見比べるために、まずはゲッターとセッターが見えていない状態のコードを見ていきます。
サンプルコード
以下のサンプルコードでは、第17章でも使ったリンコに挨拶をさせるコードです。
fun main() { val rinko = Rinko() rinko.name = "リンコ" rinko.age = 10 rinko.greet() val n = rinko.name // プロパティnameの値を変数nに代入 val a = rinko.age // プロパティageの値を変数aに代入 println("変数nの値:${n}") println("変数aの値:${a}") } class Rinko { var name = "" var age = 0 fun greet() { println("こんにちは、私の名前は${name}ピヨ!年齢は${age}歳ピヨ!") } }
出力
サンプルコードを実行すると、以下のように出力されます。
こんにちは、私の名前はリンコピヨ!年齢は10歳ピヨ! 変数nの値:リンコ 変数aの値:10
ゲッターとセッターが見えている状態のコード
続いて、ゲッターとセッターが見えている状態のコードを見ていきましょう。
サンプルコード
以下のサンプルコードは、内容自体は上記のリンコに挨拶をさせるコードと同じですが、ゲッターとセッターが見えている状態になります。
fun main() { val rinko = Rinko() rinko.name = "リンコ" // ここで、プロパティnameのset関数が呼ばれている rinko.age = 10 // ここで、プロパティageのset関数が呼ばれている rinko.greet() val n = rinko.name // ここで、プロパティnameのget関数が呼ばれている val a = rinko.age // ここで、プロパティageのget関数が呼ばれている println("変数nの値:${n}") println("変数aの値:${a}") } class Rinko { var name = "" get() { return field } set(value) { field = value } var age = 0 get() { return field } set(value) { field = value } fun greet() { println("こんにちは、私の名前は${name}ピヨ!年齢は${age}歳ピヨ!") } }
出力
サンプルコードを実行すると、以下のように出力されます。
こんにちは、私の名前はリンコピヨ!年齢は10歳ピヨ! 変数nの値:リンコ 変数aの値:10
上記のように、Kotlinが裏で記述してくれているアクセサを自分で記述してみると、先程のコードと違って長くなりますが、動作は両方とも同じで出力された文章も全く同じになりました。
また上記のコード内で出てきた「set」と「get」がアクセサになります。この「set」と「get」がプロパティの値を受け取ったり返したりする関数です。
get(ゲッター)の解説
改めてゲッターについて解説すると、インスタンス内に蓄えてある値をゲットするための関数です。
get関数の直後の「return field」の「field」は、プロパティ変数の値を指します。上記の場合では、変数nameの値のリンコや、変数ageの値の10を指します。
また「return」は値を返すことなので、リンコや10をゲットして返すということになります。
set(セッター)の解説
セッターもゲッターと同様で「field」と記述がありますが、直前に記述されたプロパティを指します。
「rinko.name = “リンコ”」の時に、nameプロパティに関連したset関数を呼び出しています。
set関数が呼び出されるときに、パラメータのvalueには「リンコ」が引き渡されます。そしてfieldにvalueの値を代入しています。
fieldはプロパティnameが格納される場所を指していて、fieldという最終的にデータが格納される先を「バッキングフィールド」と呼びます。
このアクセサは自動でKotlinが裏側で記述してくれていますが、自分で記述する場合のパラメータ変数は「value」ではなくてもなんでもOKです。
ゲッターとセッターの動きの流れはしっかり理解しておくピヨ!
【Kotlin】ゲッターやセッターを自分で記述する場面
自動で動いてくれているゲッターとセッターですが、自分で記述することもできます。最後に、ゲッターやセッターを自分で記述する場面を紹介します。
ゲッターやセッターが呼ばれたと同時に、ついでに何か処理したい場合
1つ目の自分で記述す場面は、ゲッターやセッターが呼ばれるたびに、他の処理も実行したい場合です。
サンプルコード
以下のサンプルコードでは、体重のbodyWeightの値が変更されるたびに、それに合わせたメッセージが表示されます。
fun main() { val rinko = Rinko() rinko.bodyWeight = 30 rinko.bodyWeight = 25 rinko.bodyWeight = 28 rinko.bodyWeight = 23 } class Rinko { var bodyWeight = 25 set(value) { print("体重が${field}キロから${value}キロになりました。") if(value < field) println(" -> 痩せたピヨ! ") else if(value > field) println(" -> 太ったピヨ。。") field = value } }
出力
サンプルコードを実行すると、以下のように出力されます。
体重が25キロから30キロになりました。 -> 太ったピヨ。。 体重が30キロから25キロになりました。-> 痩せたピヨ! 体重が25キロから28キロになりました。 -> 太ったピヨ。。 体重が28キロから23キロになりました。-> 痩せたピヨ!
このサンプルコードの流れは以下のようになります。
- まずプロパティbodyWeightには25が入っているので、デフォルトのfieldには25が入っていることになります。
- 最初の「rinko.bodyWeight = 30」が実行された時、30がvalueにセットされます。
- この時、valueは30でfieldは25になり、setの後のprintlnやifが実行され、出力される。
- 最後にvalueの30がfieldに代入され、bodyWeightが25から30に更新されます。
- この処理では「rinko.bodyWeight」の分、上記を繰り返しています。
クラス内に変数として実在していないものも、クラスのプロパティとして扱いたい場合
例えば、Rinkoクラスには、名前と年齢を保持するnameやageという変数が存在していますが、この情報を合わせて「自己紹介のメッセージ」にしたいとします。
今まではgreet関数の中でそのような文字列を作っていましたが、それは人間向けのメッセージとして画面に表示するだけで、どんなあいさつの文字列が表示されたかは、プログラム内のgreet関数の呼び出し側では把握できていませんでした。
これを「自己紹介のメッセージ」というプロパティとして、プログラム内で参照できるようにしてみます。
サンプルコード
以下のサンプルコードでは、プロパティnameとageを受け取った後、その2つを使ってプロパティmessageという「自己紹介のメッセージ」を作って出力しています。
fun main() { val rinko = Rinko() rinko.name = "リンコ" rinko.age = 10 println(rinko.message) rinko.age = 11 println(rinko.message) rinko.age = 12 println(rinko.message) } class Rinko { var name = "" var age = 0 val message: String get() { return "${name}ピヨ!${age}歳になったピヨ!" } }
出力
サンプルコードを実行すると、以下のように出力されます。
リンコピヨ!10歳になったピヨ! リンコピヨ!11歳になったピヨ! リンコピヨ!12歳になったピヨ!
上記のmain関数では、「rinko.message」という変数をそのままprintlnで表示しているように見えますが、実際にはmessageプロパティのゲッター関数を呼び出しています。
ゲッター関数が変数nameやageの値を組み合わせた文字列を「動的」に生成して値としています。
※「動的」にというのは、このプロパティが参照されるタイミングによって動作が変わることを意味しています
またmessageプロパティが、一度値を決めたら絶対に値が変わらない変数を定義するvalで定義されていますが、変数nameやageに何かしらの変化が起きた後にmessageプロパティを参照すると値は変化します。
ゲッターとセッターは自分で書き換えることで、いろいろなプログラムが組めるピヨ!
まとめ
この記事では、プログラミング言語であるKotlinのゲッターとセッターについて勉強していきましたが、いかがでしたでしょうか?今回の記事をまとめると以下のようになります。
- ゲッターはインスタンス内に蓄えてある値をゲットするための関数
- セッターはインスタンスのプロパティに値をセットするための関数
- ゲッターとセッターはアクセサという、裏側で自動で動いてくれる見えない関数だが、自分で書き換えることもできる
- fieldという最終的にデータが格納される先を「バッキングフィールド」と呼ぶ
- ゲッターとセッターを自分で書き換えることで、プログラムの幅が広がる
今回勉強した「ゲッター」や「セッター」はKotlinの入門レベルの知識になるので、何回も読み直してしっかり覚えておきましょう。
次回の記事では「コンストラクタ」について勉強していくピヨ!
プログラミング未経験の方や入門レベルの方、Kotlinについて詳しくなりたい方は、また一緒に勉強するピヨ!
コメント