こんにちは!リンコですピヨ!この記事では自分の勉強の復習もかねて、Kotlinでのオブジェクト式と宣言、コンパニオンオブジェクトを解説するピヨ!
この第36章では、プログラミング言語であるKotlinのオブジェクト式と宣言、コンパニオンオブジェクトについて、一緒に勉強していきましょう。
この記事を読めばプログラミング未経験の方も、Kotlinのオブジェクト式と宣言、コンパニオンオブジェクトについて1つ1つ理解しながら勉強できると思うので、是非最後まで読んで頂ければと思います。
※この記事で出てくる「サンプルコード」は、記述が長く画面からはみ出ている場合がありますが、横にスライドすると表示されるのでご安心ください。
【Kotlin】オブジェクト式とは?
まずオブジェクト式について勉強していきましょう。オブジェクト式とはどういう時に使うものなんでしょうか?
再利用を目的としないクラスを定義したい時に使う
Kotlinのプログラミングでは、再利用を目的としないその場限りのクラスを定義したい時があります。
クラスはもともと再利用することを前提として定義するものなので、クラスを定義してしまうと無駄が多い場合があります。
再利用しないけどクラスのような機能が欲しい時に、今回のオブジェクト式を使います。
アンドロイド開発でよく使う
オブジェクト式は、アンドロイドアプリの開発で多く使う場面があります。
アンドロイドアプリの開発がしたいと考えている方は、しっかりと勉強して覚えていきましょう。
再利用しないその場限りのクラスを定義したい時にオブジェクト式を使うピヨ!
【Kotlin】オブジェクト式を使ってみよう
オブジェクト式についてなんとなく理解したところで、コードの記述方法を勉強していきましょう。
オブジェクト式の書式
オブジェクト式の書式は以下のような感じです。
// 基本の記述方法 object {クラス本体} // 継承やインターフェースの実装がある場合 object: 基底クラスorインターフェース {クラス本体}
実際にオブジェクト式を使ったコードを記述してみよう
では実際に、オブジェクト式を使ったコードを記述していきます。
サンプルコード
以下のサンプルコードは、アンドロイドアプリの開発でよく使うボタンの部分のコードです。
アプリのボタンを押したら「次のページに遷移する」や「結果を表示する」など、ボタンを押した際に何かしらの処理を実行するためのコードになります。
btn.setOnClickListener(object: View.OnClickListener { override fun onClick(view: View) { ボタンを押下した際の処理 } } })
解説
まずここでオブジェクト式の宣言をしていますね。その後に続く「ビュードットオンクリックリスナー」はインターフェースになります。
(object: View.OnClickListener
その後の「{}」の部分が、クラスの本体になります。
{ override fun onClick(view: View) { ボタンを押下した際の処理 } } }
クラスの本体を見ていくと「onClick」という関数がオーバーライドされています。onClick関数は、View.OnClickListenerインターフェースにある関数です。
実装するインターフェースが持つ関数をオーバーライドしているというイメージです。
override fun onClick(view: View)
最後に処理内容が記述されています。オンクリックという名前なくらいなので、ここではボタンが押された時にここに記述されている処理が実行されます。
{ ボタンを押下した際の処理 }
上記のような感じで、オブジェクト式は使います。
また、ボタンを押した時の処理は「このボタンを押すと、この処理が行われる」という風にボタンと処理は1対1になっています。
このように1対1なので「このボタンに対してこの処理を行う」と1度記述すると、その処理は基本的に再利用せず他では使わなくなります。
ボタンがクリックされた時の処理というのは通常、クラスとして定義する必要がありますが、他では再利用しない処理をいちいちクラスとして定義してしまうと無駄が多くなるので、そういった時にオブジェクト式を使います。
アンドロイドアプリでは基本的に再利用しないクラスが頻繁に出てきますが、それを1つ1つクラスとして定義するよりもオブジェクト式を記述した方が、よりシンプルに記述できるので必然的にこのオブジェクト式を使う場面が多くなります。
アンドロイド開発がしたい人は必ず覚えるピヨ!
SAMインターフェースについて
ここまでで勉強したコードの、view.onClickListenerインターフェースが持つ抽象関数はonClick関数の1つだけでした。
このように1つしか抽象関数を持たないインターフェースのことを「SAMインターフェース」と呼びます。
※SAMはsingle abstract methodの略
また、オブジェクト式で実装するインターフェースがSAMインターフェースだと、ラムダ式でよりシンプルに記述することができます。
SAMインターフェースをラムダ式で記述することを「SAM変換」と言います。ではSAM変換はどのように記述するか見ていきましょう。
サンプルコード
先程のコードをSAM変換を使って記述するとこのようになります。
btn.setOnClickListener({ view: View -> ボタンを押下した際の処理 })
解説
めちゃくちゃ簡略化されましたね。オブジェクト式の宣言も省略されています。
ここでは、setOnClickListenerの引数にはView.OnClickListenerインターフェースを実装したクラスが入ることがわかりきっているので、このような省略が可能になります。
1つの抽象関数しか持たないインターフェースをSAMインターフェースと呼び、それをラムダ式で記述することをSAM変換というピヨ!
【Kotlin】オブジェクト宣言とは?
続いて、オブジェクト宣言について勉強していきます。
1つのインスタンスしか持たないクラス
アンドロイドアプリの開発をしていると、開発の際に1つのインスタンスしか持たないクラスを用意したい場合があります。
このような場合にオブジェクト宣言という仕組みを使うことで、1つのインスタンスしか持たないクラスを設計することができます。
ようは、そのままオブジェクトを宣言しているためインスタンス化する必要がないので、1つのインスタンスしか持たないクラスが必要な時にオブジェクト宣言を使います。
JavaでいうSingleton
他のプログラミング言語でいうと、例えばJavaではデザインパターンの一つのSingletonを使うのが一般的です。
これがKotlinの場合は、オブジェクト宣言という仕組みになります。
複数インスタンス化する必要がない時は、クラスではなくオブジェクト宣言を使うピヨ!
【Kotlin】オブジェクト宣言を使ってみよう
オブジェクト宣言についてなんとなく理解したところで、実際にコードを記述していきましょう。
オブジェクト宣言の書式
オブジェクト宣言の書式は以下のようになります。
object オブジェクト名 {オブジェクトの本体}
クラスの定義と似ていますね。最初の「class」が「object」に変わったというイメージでオッケーです。
実際にオブジェクト宣言を使ったコードを記述してみよう
では実際に、オブジェクト宣言を使ったコードを記述していってみましょう。
サンプルコード
以下のサンプルコードでは、過去の記事でも使ったリンコに挨拶をさせるコードのオブジェクト宣言バージョンになります。
fun main() { Rinko.greet() } object Rinko { val name = "リンコ" val age = 10 fun greet() { println("${name}です。${age}歳ピヨ!") } }
出力
サンプルコードを実行すると、以下のように出力されます。
リンコです。10歳ピヨ!
このようにコードを見てみると、ほとんどクラスの宣言と変わりはありませんね。
違うところと言えば、クラスの場合は「class クラス名」だっのに対し、オブジェクト宣言の場合は「object オブジェクト名」になったところです。
また大きな違いとしてはmain関数の中で、クラスの場合はクラスからインスタンスを生成してインスタンスの関数などを呼び出していたのに対し、オブジェクト宣言の場合はそのままオブジェクトの関数を呼び出すことができるというところです。
オブジェクト宣言をすることで、クラスの時のようなインスタンス化する必要がないピヨ!
【Kotlin】コンパニオンオブジェクトとは?
最後に、コンパニオンオブジェクトについて勉強していきましょう。
Staticなメンバを定義する際に利用するもの
コンパニオンオブジェクトは、KotlinでStaticメンバを定義する際に利用するためのものになります。
クラスをインスタンス化せずプロパティや関数を使えることをStaticメンバと言いますが、これを利用するためにコンパニオンオブジェクトを使います。
クラス内部でのオブジェクト宣言
また、コンパニオンオブジェクトをわかりやすく説明すると、クラス内部でのオブジェクト宣言とも言えます。
通常、クラス内のプロパティや関数にはインスタンス化しないとアクセスできませんが、クラス内でオブジェクト宣言(コンパニオンオブジェクト)することで、インスタンス化せずにアクセスできるようになります。
クラス内でオブジェクト宣言するようなことをコンパニオンオブジェクトというピヨ!
【Kotlin】コンパニオンオブジェクトを使ってみよう
コンパニオンオブジェクトについて理解したところで、実際にコードを見ていきましょう。
コンパニオンオブジェクトの書式
コンパニオンオブジェクトの書式は以下のようになります。
class クラス名 { companion object コンパニオンオブジェクト名 { 本体 } }
このように、クラス内部に「companion object コンパニオンオブジェクト名」と記述することで、処理内容をオブジェクト宣言のようにし、インスタンス化せずにプロパティや関数にアクセスすることができるようになります。
実際にコンパニオンオブジェクトを使ったコードを記述してみよう
では実際に、コンパニオンオブジェクトを使ったコードを記述して、記述方法を覚えていきましょう。
サンプルコード
以下のサンプルコードでは、Rinkoクラスを定義してその中でコンパニオンオブジェクトを使って、リンコに挨拶をさせています。
fun main() { Rinko.greet() } class Rinko { companion object RinkoGreet { val name = "リンコ" val age = 10 fun greet() { println("${name}です。${age}歳ピヨ!") } } }
出力
サンプルコードを実行すると、以下のように出力されます。
リンコです。10歳ピヨ!
このコードでは、まずRinkoクラスを定義しています。
class Rinko {
その次のコードで、コンパニオンオブジェクトを記述しています。このように記述することで、クラス内部でオブジェクト宣言したような感じになります。
companion object RinkoGreet {
最後にコンパニオンオブジェクトの本体ですね。
val name = "リンコ" val age = 10 fun greet() { println("${name}です。${age}歳ピヨ!") }
そしてコンパニオンオブジェクトを使うことで、main関数ではインスタンス化せずとも、Rinkoクラスのgreet関数を呼び出すことができています。
fun main() { Rinko.greet() }
コンパニオンオブジェクトの名前は省略可能
最後に、コンパニオンオブジェクトの名前は省略することが可能になっています。
先程のコードで言うと「companion object RinkoGreet」の「 RinkoGreet」の部分ですね。
省略すると以下のようになります。
fun main() { Rinko.greet() } class Rinko { companion object { val name = "リンコ" val age = 10 fun greet() { println("${name}です。${age}歳ピヨ!") } } }
コンパニオンオブジェクトの名前を省略しても。省略する前と同じように結果が出力されるので安心してください。
コンパニオンオブジェクトの名前を省略してもオッケーピヨ!
まとめ
この記事では、プログラミング言語であるKotlinのオブジェクト式と宣言、コンパニオンオブジェクトについて勉強していきましたが、いかがでしたでしょうか?今回の記事をまとめると以下のようになります。
- 再利用を目的としないその場限りのクラスを定義したい時にオブジェクト式を使う
- 1つの抽象関数しか持たないインターフェースをSAMインターフェースと言う
- SAMインターフェースをラムダ式で記述することをSAM変換と言う
- インスタンスを1つしか持たないクラスが必要な時にオブジェクト宣言を使う
- オブジェクトのプロパティや関数を呼び出す際は、インスタンス化の必要がない
- インスタンス化せずにクラスのプロパティや関数にアクセスできるようにすることをコンパニオンオブジェクトと言う
- コンパニオンオブジェクトの名前を省略しても良い
今回勉強した「オブジェクト式」や「オブジェクト宣言」や「コンパニオンオブジェクト」は難しくややこしいと思うので、何回も読み直してしっかり覚えておきましょう。
次回の記事では「ネストクラス」について勉強していくピヨ!
プログラミング未経験の方や入門レベルの方、Kotlinについて詳しくなりたい方は、また一緒に勉強するピヨ!
コメント