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でインターフェイスがどのように機能するかを誤解していますか?
Javaコードは、SAM変換(ラムダから単一の抽象メソッドを使用したインターフェースへの自動変換)に依存しています。 SAM変換は 現在サポートされていません Kotlinで定義されたインターフェースの場合。代わりに、インターフェイスを実装する匿名オブジェクトを定義する必要があります。
val obj = object : MyInterface {
override fun onLocationMeasured(location: Location) { ... }
}
最善の解決策は、Javaインターフェイスの代わりにtypealiasを使用することです
typealias MyInterface = (Location) -> Unit
fun addLocationHandler(myInterface:MyInterface) {
}
次のように登録します。
val myObject = { location -> ...}
addLocationHandler(myObject)
またはさらにクリーナー
addLocationHandler { location -> ...}
次のように呼び出します。
myInterface.invoke(location)
現在の3つのオプションは次のようです。
ライブラリをKotlinに変換するとき、KotlinからのKotlinよりもKotlinからJavaを呼び出す方がきれいだったため、実際にはすべてのインターフェイスをJavaコードに残しました。
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
このようにインターフェースにアクセスしてみてください:
object : MyInterface {
override fun onSomething() { ... }
}