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