はじめに
ひょんな事からKotlinを勉強することになりました。
私は普段はPHPやRubyのようなサーバーサイドスクリプト言語を使っており、あまりJavaに触れる機会がないため、拙い説明になってしまうかもしれません。
とはいえ、せっかく勉強をしているので、記事にしたいと思います。
勉強に使用した本はKotlinイン・アクションになります。
また、動作確認にはkotlincを使用しました。
インターフェース
基本
Kotlinだと interface
キーワードを使うことで定義できます。
1 2 3 | interfaceClickable{ fun click() } |
これをクラスで実装するためには、
1 2 3 | classButton:Clickable{ override fun click()=println("I was clicked") } |
Javaでいう@override
アノーテーションの代わりにKotlinではoverride
修飾詞をつける必要があります。これは必須です。
実際にやってみます。
1 2 | >>>Button.click() Iwas clicked |
試しに、override
をつけないで実装しようとします。
すると、下記のようなコンパイルエラーが出ます。
1 2 | error:'click'hides member of supertype'Clickable'andneeds'override'modifier fun click()=println("I was clicked") |
- インターフェースは複数実装できる。
- クラスは1つしか継承できない。
override
修飾詞は必須。つけないなら同じメソッド名を使わない。
デフォルト実装付メソッド
インターフェースにデフォルトで定義しておくこともできます。
1 2 3 4 | interfaceClickable{ fun click() fun showOff()=println("I'm clickable!!") } |
デフォルト実装があるなら、具象クラスで再定義しなくても大丈夫です。
1 2 3 | classButton:Clickable{ override fun click()=println("I was clicked") } |
1 2 3 4 | >>>Button().click() Iwas clicked >>>Button().showOff() I'mclickable!! |
同じメソッド名を持つ複数のインターフェース
同様に、
1 2 3 4 | interfaceFocusable{ fun setFocus(b:Boolean)=println("I ${if (b) "got" else "lost"} focus.") fun showOff()=println("I'm focusable!!") } |
Clickable
と Focusable
を実装してみると、エラーになってしまいます。
1 2 3 4 | classButton:Clickable,Focusable error:class'Button'must override publicopen fun showOff(): Unit defined inLine_15.Clickable because it inherits multiple interfacemethods of it |
同一メソッド名を持つ場合は、明示的にどちらのメソッドを使用するか宣言する必要があります。
1 2 3 4 5 6 7 8 | classButton:Clickable,Focusable{ override fun click()=println("I was clicked") override fun showOff(){ super<Clickable>.showOff() super<Focusable>.showOff() } } |
Javaだと Clickable.super.showOff()
になるところです。
実際に試してみます。
1 2 3 | >>>Button().showOff() I'm clickable!! I'mfocusable!! |
修飾子
open
Javaだと、明示的にfinal
をつけなければ、全てのメソッドをオーバーライドできます。
ただ、Kotlinだとデフォルトがfinal
になります。
もし、そのクラスのサブクラスを作成したい場合は、open
をつける必要があります。
1 2 3 4 5 6 7 8 9 10 | open classRichButton:Clickable(){ // 普通にメソッドを宣言した場合は、サブクラスでオーバーライドできない fun disable(){} // open をつければオーバーライド可能 open fun animate(){} // override したメソッドはデフォルトで open になる override fun click(){} // final をつければ、 override したメソッドでもサブクラスでオーバーライドできない finaloverride fun showOff(){} } |
abstract
abstract
をつけた抽象クラスはインスタンス化はできない。interface
と同様、抽象メンバは常にopen
。- 非抽象メンバはデフォルトでは
open
ではないが、open
にすることもできる。
1 2 3 4 5 6 7 8 9 10 | abstractclassAnimated{ abstractfun animate() // 非抽象メンバ open fun stopAnimating(){ } fun animateTwice(){ } } |
可視性修飾子
public
どこからも参照可能internal
モジュール内からのみ参照可能protected
サブクラスから参照可能private
クラス内からのみ参照可能(トップレベルだとファイル内からのみ参照可能)
internal
というのは初めて見ました。
モジュールはコンパイル後のひとまとまりを指すそうです。
さいごに
勉強のまとめとして記事にさせていただきました。
他にもネストしたクラスやシールドクラスなどの解説も読んだのですが、まだ私の中で腑に落ちていないため、改めて記事にしたいと思います。