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