カテゴリー: BackEnd

PHPerだけどKotlinを勉強したって良いよね その1〜クラス編〜

はじめに

ひょんな事から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")
  • インターフェースは複数実装できる。
  • クラスは1つしか継承できない。
  • `override`修飾詞は必須。つけないなら同じメソッド名を使わない。

デフォルト実装付メソッド

インターフェースにデフォルトで定義しておくこともできます。

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!!

修飾子

open

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

  • `abstract`をつけた抽象クラスはインスタンス化はできない。
  • `interface`と同様、抽象メンバは常に`open`。
  • 非抽象メンバはデフォルトでは`open`ではないが、`open`にすることもできる。
abstract class Animated {
    abstract fun animate()
    // 非抽象メンバ
    open fun stopAnimating() {

    }
    fun animateTwice() {

    }
}

可視性修飾子

  • public どこからも参照可能
  • internal モジュール内からのみ参照可能
  • protected サブクラスから参照可能
  • private クラス内からのみ参照可能(トップレベルだとファイル内からのみ参照可能)

`internal`というのは初めて見ました。
モジュールはコンパイル後のひとまとまりを指すそうです。

さいごに

勉強のまとめとして記事にさせていただきました。
他にもネストしたクラスやシールドクラスなどの解説も読んだのですが、まだ私の中で腑に落ちていないため、改めて記事にしたいと思います。

naoki85

シェア
執筆者:
naoki85
タグ: Kotlin

最近の投稿

フロントエンドで動画デコレーション&レンダリング

はじめに 今回は、以下のように…

3週間 前

Goのクエリビルダー goqu を使ってみる

はじめに 最近携わっているとあ…

1か月 前

【Xcode15】プライバシーマニフェスト対応に備えて

はじめに こんにちは、suzu…

2か月 前

FSMを使った状態管理をGoで実装する

はじめに 一般的なアプリケーシ…

3か月 前