logo サブスレッド

Kotlinで複数の実装が必要なinterfaceでの無名クラスの書き方

はじめに

金曜担当のしみずです。どうぞよろしく。

すみません、忙しくて先週の原稿を落としてしまいました。
今週からまたきちんと書きたいと思います。

Android開発のトレンドはKotlinということで、少しだけ触ってます。
新しい言語なので仕様が分からず初歩的なことでつまずきました。
それは2つ以上のメソッドを実装する必要があるinterfaceの無名クラスによる実装方法です。

調べてもinterfaceメソッドが1つの場合のやり方(SAM変換の説明)しかヒットしなくて
調べるのに少し苦労したのですが実装方法がわかったので書いていきます。

interfaceのメソッド1つの場合

先にも書きましたがKotlinのSAM変換というのが使えます。
SAM変換というのは、簡単に言うとJava側で実装すべきメソッドが1つの場合のinterfaceのみ、諸々省略して書ける方法です。

Java

interface TestInterface1 {
    public void hoge(int arg);
}

class TestClass1 {
    public void setTestInterface(TestInterface1 if1);
}

Kotlin

val testClass1 = TestClass1()

// こうも書けるし
testClass1.setTestInterface({ arg -> System.out.printlin("何か処理") })

// ()を外して書くこともできる!
testClass1.setTestInterface{ arg -> System.out.printlin("何か処理") }

// 複数行だっていける!
testClass1.setTestInterface{ arg ->
    System.out.printlin("処理1")
    System.out.printlin("処理2")
    System.out.printlin("処理3")
}

これはいいですね。
Javaで冗長なコードを書いていたのが嘘のようです。

ちなみに冗長なJavaコードはこちら

Java

TestClass1 testClass1 = new testClass1();

// 冗長!
testClass1.setTestInterface(new TestInterface1() {
    System.out.pirntln("何か処理");
});

interfaceのメソッドが2つ以上の場合

今回、事の発端となったメソッドが2つ以上の場合の実装方法です。

Java

interface TestInterface2 {
    public void fuga();
    public void piyo();
}

class TestClass2 {
    public void setTestInterface(TestInterface2 if2);
}

Kotlin

val testClass2 = TestClass2()

// こう書きます(Javaみたいな感じ)
testClass2.setTestInterface(object : TestInterface2 {
    override fun fuga() {
        System.out.println("何か処理")
    }

    override fun piyo() {
      System.out.println("何か処理")
    }
})

[余談]Kotlinで定義したinterfaceの場合はSAM変換でエラーが出てしまう

ちょっと余談ですが記事作成のためのテストコードを書いてるときにハマったので、せっかくですし書いておきます。
Kotlinで書いたinterface、classのメソッドに対してはSAM変換が使えないようでエラーが出てしまいます。

先に説明したJava側のコードをKotlinで書きます。

Kotlin

interface TestInterface1 {
    fun hoge(arg : Int)
}

class TestClass1 {
    fun setTestInterface(if1 : TestInterface1)
}

で、これを以下のようにKotlinでSAM変換のコードを書くとエラーになるのです。

Kotlin

val testClass1 = TestClass()

// エラー
testClass1.setTestInterface({ arg -> System.out.printlin("何か処理") })

// エラー
testClass1.setTestInterface{ arg -> System.out.printlin("何か処理") }

interfaceまたはメソッドのいずれかが片方でもKotlinのコードの場合にエラーがでるみたいです。
説明のために書いていたコードは全部Kotlinだったので、原因が分かるまで時間がかかった・・・

ただ、Androidの既存のクラスライブラリを使う分には十分に恩恵が受けられそうです。

おわりに

笑点の司会者が変わりましたね。昇太さんですか。
個人的にはいちばん無難なところだなぁと思いました。
笑点は小さい頃から見ていて、その頃は円楽師匠が司会でした。
いまの紫じゃないですよ。今の圓楽(旧:楽太郎)の前の円楽師匠です。

冒頭でも書きましたが、忙しかったので昇太さんの司会を一度も見ていないですが
世間の評判は上々のようです。
今週は見れそうなので楽しみです。

週間、ウチのネコ。第5号

仕事の邪魔をするウチのネコ

現在の位置:サブスレッド ホーム > 技術ブログ > Kotlinで複数の実装が必要なinterfaceでの無名クラスの書き方