Search

Functional Interface

추상 메서드가 하나만 있는 인터페이스를 함수형 인터페이스 또는 단일 추상 메서드(SAM) 인터페이스라고 한다.
함수형 인터페이스는 여러 개의 추상이 아닌 멤버를 가질 수 있지만 추상 멤버는 하나만 가질 수 있다.
함수형 인터페이스를 선언하려면 fun 수정자를 사용한다.
fun interface KRunnable { fun invoke() }
Kotlin
복사

SAM 변환

람다 표현식을 사용하여 코드를 더 간결하고 읽기 쉽게 만드는 SAM 변환을 사용할 수 있다.
함수형 인터페이스를 수동으로 구현하는 클래스를 만드는 대신 람다 표현식을 사용할 수 있다.
람다 표현식의 시그니처가 인터페이스의 단일 메서드 시그니처와 일치할 때 해당 인터페이스 구현을 동적으로 생성하는 코드로 변환할 수 있다.
// 함수형 인터페이스 fun interface IntPredicate { fun accept(i: Int): Boolean } // SAM 변환을 사용하지 않은 경우 val isEven = object : IntPredicate { override fun accept(i: Int): Boolean { return i % 2 == 0 } } // SAM 변환을 사용하는 경우 val isEven = IntPredicate { it % 2 == 0 }
Kotlin
복사

함수형 인터페이스 생성자에 대한 호출 참조

Kotlin 1.6.20 이전의 인터페이스의 생성자 함수
// Printer 인터페이스와 이 인터페이스를 구현하는 익명 객체를 반환하는 생성자 함수를 정의하는 코드 interface Printer { fun print() } fun Printer(block: () -> Unit): Printer = object : Printer { override fun print() = block() }
Kotlin
복사
Kotlin 1.6.20 이후의 함수형 인터페이스의 생성자 함수
함수형 인터페이스는 자동으로 생성자를 가지게 된다.
:: 키워드를 통해 함수 참조를 사용할 수 있다.
// fun interface Printer { fun print() } documentsStorage.addPrinter(::Printer)
Kotlin
복사
두 버전 사이 호환성을 유지하기 위해 @Deprecated 어노테이션을 사용할 수 있다.
@Deprecated(message = "Your message about the deprecation", level = DeprecationLevel.HIDDEN) fun Printer(block: () -> Unit): Printer = object : Printer { override fun print() = block() }
Kotlin
복사

함수형 인터페이스 VS 타입 별칭

타입 별칭
기존 타입에 대한 새로운 이름을 정의하는 기능이다.
새로운 타입을 생성하지 않고 기존 타입에 대한 가독성을 높이기 위해 사용한다.
typealias 키워드를 사용한다.
typealias IntPredicate = (i: Int) -> Boolean val isEven: IntPredicate = { it % 2 == 0 } fun main() { println("7은 짝수인가? - ${isEven(7)}") // 출력: 7은 짝수인가? - false }
Kotlin
복사
함수형 인터페이스
단일 추상 메서드를 가지는 인터페이스로 함수형 타입을 객체로 래핑할 수 있게 해준다.
함수형 인터페이스는 여러 개의 비추상 멤버를 가질 수 있으며 다른 인터페이스를 구현하거나 확장할 수 있다.
fun interface IntPredicate { fun test(i: Int): Boolean } val isEven: IntPredicate = IntPredicate { it % 2 == 0 } fun main() { println("7은 짝수인가? - ${isEven.test(7)}") // 출력: 7은 짝수인가? - false }
Kotlin
복사
차이점
1.
타입 생성
a.
타입 별칭 : 기존 타입에 대한 새로운 이름만 정의할 뿐 새로운 타입을 생성하지 않는다.
b.
함수형 인터페이스 : 새로운 타입을 생성하며 이를 통해 보다 복잡한 기능을 구현할 수 있다.
2.
멤버 수
a.
타입 별칭 : 하나의 함수 타입만을 나타낼 수 있다.
b.
함수형 인터페이스 : 여러 개의 비추상 멤버를 가질 수 있으며 하나의 추상 멤버를 가질 수 있다.
3.
확장 및 구현
a.
타입 별칭 : 다른 인터페이스를 구현하거나 확장할 수 없다.
b.
함수형 인터페이스 : 다른 인터페이스를 구현하거나 확장할 수 있다.
4.
확장 함수
a.
타입 별칭 : 확장 함수를 정의할 수 없다.
b.
함수형 인터페이스 : 특정 함수형 인터페이스에 대해 확장 함수를 정의할 수 있다.
선택 기준
특정 매개변수와 반환 타입을 가지는 함수를 받아야 하는 API 에서는 단순한 함수 타입이나 타입 별칭을 사용하는데 좋다.
typealias StringTransformer = (String) -> String
Kotlin
복사
함수 이상의 비즈니스 로직이나 계약을 가지고 있는 복잡한 엔티티가 필요한 경우 함수형 인터페이스를 선언하는 것이 좋다.
fun interface StringTransformer { fun transform(input: String): String // 추가적인 비추상 멤버와 메서드를 정의할 수 있습니다. }
Kotlin
복사