web-dev-qa-db-ja.com

Kotlin:インターフェース...にはコンストラクタがありません

Javaコードの一部をKotlinに変換していますが、Kotlinコードで定義されているインターフェイスをインスタンス化する方法がよくわかりません。例として、インターフェイス(Javaコードで定義)があります:

public interface MyInterface {
    void onLocationMeasured(Location location);
}

さらに、Kotlinコードでこのインターフェイスをインスタンス化します。

val myObj = new MyInterface { Log.d("...", "...") }

そしてそれは正常に動作します。ただし、MyInterfaceをKotlinに変換すると:

interface MyInterface {
    fun onLocationMeasured(location: Location)
}

エラーメッセージが表示されます:インスタンス化しようとするとInterface MyListener does not have constructors-構文以外は何も変わっていないようです。 Kotlinでインターフェイスがどのように機能するかを誤解していますか?

93
Aleph Aleph

Javaコードは、SAM変換(ラムダから単一の抽象メソッドを使用したインターフェースへの自動変換)に依存しています。 SAM変換は 現在サポートされていません Kotlinで定義されたインターフェースの場合。代わりに、インターフェイスを実装する匿名オブジェクトを定義する必要があります。

val obj = object : MyInterface {
    override fun onLocationMeasured(location: Location) { ... }
}
161
yole

最善の解決策は、Javaインターフェイスの代わりにtypealiasを使用することです

typealias MyInterface = (Location) -> Unit

fun addLocationHandler(myInterface:MyInterface) {

}

次のように登録します。

val myObject = { location -> ...}
addLocationHandler(myObject)

またはさらにクリーナー

addLocationHandler { location -> ...}

次のように呼び出します。

myInterface.invoke(location)

現在の3つのオプションは次のようです。

  • typealias(Javaから呼び出されると厄介です)
  • kotlinインターフェース(kotlinから呼び出された場合は面倒です;オブジェクトを作成する必要があります)これはIMOの大きな後退です。
  • Javaインターフェース(kotlinから呼び出されたときは面倒ではありません;ラムダはオブジェクトを必要としないようにインターフェース名を前に付ける必要があります;また、関数の括弧規則の外でラムダを使用できません)

ライブラリをKotlinに変換するとき、KotlinからのKotlinよりもKotlinからJavaを呼び出す方がきれいだったため、実際にはすべてのインターフェイスをJavaコードに残しました。

15
Steven Spungin

Javaクラスがある場合:

recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerView, new RecyclerTouchListener.ClickListener()
        {
              //Your Code
        }));

このコードをJavaからKotlinに変換する必要があります:

override fun showJozList (list : List<ResponseGetJuzList.Parameter4>) {
        adapter.addData(list)
        jozlist_recycler.addOnItemTouchListener(RecyclerTouchListener(
                activity ,
                jozlist_recycler ,
                object : RecyclerTouchListener.ClickListener
                    {
                          //Your Code
                    }))

変換Javaインターフェース

new RecyclerTouchListener.ClickListener()

to Kotlin Interfaceスタイル:

object : RecyclerTouchListener.ClickListener
5

このようにインターフェースにアクセスしてみてください:

 object : MyInterface {
    override fun onSomething() { ... }
}
4
Jéwôm'