Kotlin/Kotlin In Action

[Kotlin] 3-2. 확장 함수 (extension function)

gudwnsgur 2022. 6. 3. 18:27
728x90

∘ 기존 자바 API를 재작성하지 않고도 코틀린이 제공하는 편리한 기능을 사용할 수 있다??!!

∘ 확장함수는 이를 가능하게 한다.

 

ex) String 변수를 LocalDate 형식으로 변환하고 싶다.

 

// 확장함수를 쓰지 않으면
 fun main() {
    val str = "20220603"
    val localDate = getLocalDate(str)
    println(localDate) // 2022-06-03
}

fun getLocalDate(str: String): LocalDate {
    return LocalDate.parse(str, DateTimeFormatter.ofPattern("yyyyMMdd"))
}

 

∘ 이렇게 매번 함수를 만들어서 사용하고 싶지 않다면

 

// 확장함수 사용
fun main() {
    val str = "20220603"
    val localDate = str.toLocalDate()
    println(localDate) // 2022-06-03
}

// String : 수신객체 타입
fun String.toLocalDate(): LocalDate {
    // this : 수신객체
    return LocalDate.parse(this, DateTimeFormatter.ofPattern("yyyyMMdd"))
}

 

∘ LocalDate 타입으로 변환해주는 String의 확장함수 toLocalDate()를 만들어놓고 사용하자!

 

∘ 확장 함수는 캡슐화를 깨지 않는다.

확장 함수 내에서는 private/protected 멤버를 사용할 수 없다.

확장 함수를 호출하는 쪽(예제의 main)에서는 확장함수와 멤버함수를 구분할 수 없고, 구분할 필요도 없다.


[ import & extension function ]



extension function을 사용하려면 해당 함수가 정의된 클래스를 import 해야한다.

import strings.toLocalDate

import strings.*

import strings.toLocalDate as localdate

 


[ 확장함수는 오버라이드할 수 없다. ]

 

interface View {
    fun click() = println("View Clicked")
}

class Button: View {
    override fun click() {
        println("Button Clicked")
    }
}

fun main() {
    val button: View = Button()
    val button2 = Button()

    button.click() // Button Clicked
    button2.click() // Button Clicked
}

 

 Button class는 View 인터페이스를의 구현체이며 click()함수를 오버라이드 하고있다.

button 변수는 실제 타입이 Button class이므로 오버라이드된 click함수가 호출된다.

 

하지만 확장함수에서는?

 

fun View.showOff() = println("I'm view!")
fun Button.showOff() = println("I'm button!!")

interface View

class Button: View

fun main() {
    val button: View = Button()
    val button2 = Button()

    button.showOff() // I'm view!
    button2.showOff() // I'm button!
}



 확장 함수는 정적 자바 메소드로 컴파일하기 때문에 View 인터페이스의 button은 View의 확장함수인 View.showOff()가 호출된다.

 

728x90