티스토리 뷰
발단
오브젝트가 함수형 인터페이스면 접두어로 인터페이스 파입을 가진 람다를 생성할 수 있다하여 따라해봄.
@FunctionalInterface
interface FunctionalInterface {
fun apply()
}
fun main() {
val f = FunctionalInterface { println() } // error??
}
그런데 생성이 안되고 에러가 발생함.. 뭐지??
함수형 인터페이스를 잘못 선언했나 해서 기존에 있는 클래스를 가지고 다시 시도해봄.
fun main() {
val r = Runnable { println("run!") }
r.run() // run!
}
이건 잘됨;;; 뭐지??
그래서 Runnable을 코틀린으로 가져와 다시 시도해봄
@FunctionalInterface
interface RunnableKotlin {
fun run()
}
fun main() {
val r = RunnableKotlin { println("kotlin run!!") } // error
}
마찬가지로 또 에러발생;; 뭐지???
스택 오버플로우 검색해보니...
Your Java code relies on SAM conversion - an automatic conversion of a lambda into an interface with a single abstract method. SAM conversion is currently not supported for interfaces defined in Kotlin.
훔..... SAM Conversion????
SAM Conversion
- SAM은 Single Abstract Method의 약자로 코틀린의 함수 리터럴을 자동으로 자바의 함수형 인터페이스로 교체해 준다.
- 즉, SAM Conversion은 자바로 작성한 Functioncal Interface에서만 동작하여 코틀린으로 작성시에는 사용하지 못한다.
- 이 기능은 자바와 상호 운영성 측면에서 나왔으며 코틀린의 경우 함수형 인터페이스가 아닌 함수타입으로 선언이 가능하다.
//Java
@FunctionalInterface
public interface JavaFunctionalInterface {
void apply();
}
//Kotlin
fun main() {
val f = JavaFunctionalInterface { println("java functional interface") }
f.apply() // java functional interface
}
interface KotlinFunctionalInterface { fun apply() }
class KotlinFunctionalClass(val f: KotlinFunctionalInterface)
class KotlinFunctionalClassAnother(val f: () -> Unit) // 함수형 타입으로 파라미터 선언
class JavaFunctionalClass(val f: JavaFunctionalInterface)
fun main() {
val j = JavaFunctionalInterface { println("java functional interface") }
JavaFunctionalClass(JavaFunctionalInterface { println("") })
j.apply() // java functional interface
// val k = KotlinFunctionalClass { println("java functional interface") } // error
val k = KotlinFunctionalClassAnother(f = { println("kotlin lambda") })
k.f.invoke() // kotlin lambda
}
위와 같이 자바에서 선언한 함수형 인터페이스는 SAM Conversion이 가능하지만 코틀린에서 선언한 함수형 인터페이스는 사용하지 못한다.
만약 함수형 파라미터를 받고자 한다면 인터페이스가 아닌 함수형 파라미터를 선언해서 사용해야한다.
val f: () -> Unit
만약 위의 함수형 타입 선언이 장황하거나 재사용 또는 가독성 측면에서 typealias를 사용할 수도 있다.
typealias emptyFuncType = () -> Unit
class KotlinFunctionalClassAnother(val f: emptyFuncType) // 함수형 타입으로 파라미터 선언
fun main() {
val k = KotlinFunctionalClassAnother(f = { println("kotlin lambda") })
k.f.invoke() // kotlin lambda
}
출처
https://thdev.tech/kotlin/androiddev/2017/10/07/Kotlin-SAM/
Kotlin SAM(Single Abstract Method)을 사용하는 방법
개인 광고 영역 Kotlin에는 SAM Conversions이 제공됩니다. Single Abstract Method의 약자로 SAM이라고 합니다. 이름에서 알 수 있듯 SAM은 하나의 추상 메서드에 대해서 lambdas 식을 제공합니다. 단, Java에서 작성한 Interface 정의와 이를 활용하는 setOnClickListener를 kotlin에서 부르는 경우에만 이에 해당합니다. 코틀린에서 유용해야 하는데 실제로는 kotlin에서 작성한 interf
thdev.tech
https://makeappeasy.com/android/2018/08/21/sam-in-kotlin/
SAM in Kotlin – Android
SAM(Single Abstract Method) : Kotlin은 SAM conversion을 지원하지 않는다. 좀 더 정확히 말하면 Kotlin으로 작성되었을 경우에 지원하지 않는다. 왜냐하면 함수 타입 선언으로 가능하기 때문이다. 말이 좀 어렵다. 먼저 자바에서 어떻게 사용되는지 부터 보자. public interface Callable{ void call(String value); } public interface Callable{ voi
makeappeasy.com
https://stackoverflow.com/questions/43737785/kotlin-interface-does-not-have-constructors
Kotlin: Interface ... does not have constructors
I am converting some of my Java code to Kotlin and I do not quite understand how to instantiate interfaces that are defined in Kotlin code. As an example, I have an interface (defined in Java code):
stackoverflow.com
'개발 언어 > 코틀린' 카테고리의 다른 글
코틀린(Kotlin) | 클래스 - Enum (0) | 2019.06.24 |
---|---|
코틀린(Kotlin) | 클래스 - 프로퍼티(Property) (2) | 2019.06.24 |
코틀린(Kotlin) | 클래스 - 중첩 클래스와 내부 클래스 (0) | 2019.06.24 |
코틀린(Kotlin) | 제네릭 (Generic) (0) | 2019.06.23 |
코틀린(Kotlin) | 클래스 - 데이터 클래스 (0) | 2019.06.22 |