[java] 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에서 인터페이스의 작동 방식을 이해하지 못합니까?



답변

Java 코드는 SAM 변환 (람다를 단일 추상 메소드를 사용하여 인터페이스로 자동 변환)에 의존합니다. Kotlin에 정의 된 인터페이스 에는 현재 SAM 변환이 지원되지 않습니다 . 대신 인터페이스를 구현하는 익명 객체를 정의해야합니다.

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


답변

가장 좋은 솔루션은 Java 인터페이스 대신 유형을 사용하는 것입니다.

typealias MyInterface = (Location) -> Unit

fun addLocationHandler(myInterface:MyInterface) {

}

다음과 같이 등록하십시오 :

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

또는 심지어 클리너

addLocationHandler { location -> ...}

다음과 같이 호출하십시오.

myInterface.invoke(location)

현재 3 가지 옵션은 다음과 같습니다.

  • typealias (자바에서 호출하면 더러워 짐)
  • kotlin 인터페이스 (kotlin에서 호출 할 때 더러워지고 개체를 만들어야 함) 이것은 IMO의 큰 단계입니다.
  • 자바 인터페이스 (kotlin에서 호출 할 때 덜 지저분 해집니다. 람다는 앞에 인터페이스 이름이 필요하므로 객체가 필요하지 않으며 함수 괄호 규칙 외부에서 람다를 사용할 수 없습니다)

라이브러리를 Kotlin으로 변환 할 때 Kotlin의 Kotlin보다 Kotlin에서 Java를 호출하는 것이 더 깨끗했기 때문에 실제로 모든 인터페이스를 Java 코드로 남겨 두었습니다.


답변

다음과 같이 인터페이스에 액세스하십시오.

 object : MyInterface {
    override fun onSomething() { ... }
}


답변

다음 과 같은 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()

코 틀린 인터페이스 스타일 :

object : RecyclerTouchListener.ClickListener


답변

인터페이스가 클래스의 리스너 메소드 용인 경우 인터페이스 정의를 함수 유형으로 변경하십시오. 코드가 더 간결 해집니다. 다음을 참조하십시오.

리스너 정의를 포함하는 클래스

// A class
private var mLocationMeasuredListener = (location: Location) -> Unit = {}

var setOnLocationMeasuredListener(listener: (location: Location) -> Unit) {
    mLocationMeasuredListener = listener
}

// somewhere in A class
mLocationMeasuredListener(location)

다른 수업

// B class
aClass.setOnLocationMeasuredListener { location ->
    // your code
}


답변

class YourClass : YourInterface {
    override fun getTest() = "test"
}

interface YourInterface {
    fun getTest(): String
}

val objectYourClass: YourInterface = YourClass()
print(objectYourClass.getTest())


답변