Kotlinでコンストラクタを書く
Kotlinで一からクラスを書く必要が出てきてかなり面食らったのでメモ。 KotlinのM11が一般的になる頃にまた追記しよう...。
参考: http://dev.classmethod.jp/smartphone/android-kotlin-introduction-04/ http://qiita.com/omochimetaru/items/98e015b0b694dd97f323
プライマリコンストラクタとセカンダリコンストラクタについて
これ、絶対Java
にもあるでしょう、と思っても私が師事しているGoogle先生は教えてくれなかったので、
たぶん、Kotlin
とかScala
とかC#
とかのものでそんなにJava
のものではないのかもしれません。
Kotlin
の場合、プライマリコンストラクタはクラス定義と一緒に定義されるコンストラクタであり、一見するとコンストラクタと思い難いため、初見ではかなり理解し難かったです。
プロパティの初期値やCompanion Object
の定義と初期化処理を設定することができます。
プライマリコンストラクタ以外のコンストラクタをセカンダリコンストラクタと言います。
セカンダリコンストラクタからはプライマリコンストラクタを this
で呼び出すことが出来ます。
セカンダリコンストラクタは基本的にクラスブロックの中にあるので比較的コンストラクタっぽい見た目です。
プライマリコンストラクタを書く
参考: http://dev.classmethod.jp/smartphone/android-kotlin-introduction-04/
プライマリコンストラクタはクラス定義と同時に書きます。
public class Music(title:String) { val musicTitle = title }
この、クラス定義のような顔をして書いてあるものがプライマリコンストラクタです。
このプライマリコンストラクタではval
, var
といったプロパティの定義やcompanion object
の定義、初期値の設定が出来ます。
public class Music(title:String) { val musicTitle = title companion object { fun create(): Music = Music() } }
では、コンストラクタで初期化ついでにあれこれ処理を行いたい、といった場合はどう書くかというと、init
ブロックで書きます。
public class Music(title:String) { val musicTitle = title init { println("Music title ${title} is instantiated.") } companion object { fun create(): Music = Music() } }
Javaでいうsuper()
をコンストラクタでどう書くかというと
public class Music extends Hobby { public Music(String title) { super() this.musicTitle = title } }
の場合、以下のようになります。
public class Music(title:String) : Hobby() { val musicTitle = title }
なるほどー。
セカンダリコンストラクタを書く
セカンダリコンストラクタはconstructor()
を使っていくつでも書けます。
プライマリコンストラクタと引数の数が揃っている必要もありません。
public class Music(title:String) : Hobby() { val musicTitle = title constructor(title: String, price: Int) {} constructor(title: String, category: String) {} }
セカンダリコンストラクタの中でプライマリコンストラクタを呼びたい場合、以下のようにthis
を使います。
public class Music(title:String) { val musicTitle = title constructor(title: String, price: Int): this(title) { } }
そういえば、関係ないのですが、あるコンストラクタから別のコンストラクタを呼ぶ処理が出てきて、あんまり触れたことがなかったので驚きました...。
コンストラクタでないsuperは使える
おまけになのですが、コンストラクタの継承というか、コンストラクタ周りの継承が特殊なだけで、それ以外のsuper()
は普通に使えるみたいです。
// 申し訳程度の例 pubic class Hobby(title:String) { public fun play() { println("I'm plating ${title}") } } public class Music(title:String) : Hobby(title:String){ val musicTitle = title constructor(title: String, price: Int): this(title) { } override public fun play() { println("♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪") super() println("♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪") } }