실무 프로젝트로 배우는 Kotlin & Spring/코틀린 고급

확장 함수

webmaster 2022. 10. 9. 18:38
728x90
fun String.first(): Char { //확장대상.메서드명, 확장대상.변수명 을 써서 확장함수를 작성할 수 있다.
    //확장함수는 항상 자바코드로 변환하면, 자기 자신을 첫번쨰 인자로 받는다.
    return this[0] //함장함수 내부에서 쓰이는 this 를 리시버, 수신자 객체라 부른다.
}

fun String.addFirst(char: Char): String {
    return char + this.substring(0)
}

class MyExample{
    fun printMessage() = println("클래스 출력")
}

//fun MyExample.printMessage() = println("확장 출력") //기존에 존재하는 메서드를 확장함수로 정의한다면?
fun MyExample.printMessage(message: String) = println(message) //인자가 다르면 잘 동작한다(시그니처가 다르기 떄문)

fun MyExample?.printNullOrNotNull(){
    if(this == null) println("널인 경우에만 출력")
    else println("널이 아닌 경우에만 출력")
}

fun main() {
    //println("ABCD".first()) //A
    //println("ABCD".addFirst('Z')) //ZABCD
    /*
    MyExample().printMessage() //클래스가 직접 보유하는 맴버 클래스의 메서드가 우선 순위가 높다.
    //코틀린 버젼이 올라가면서, 기존 클래스에 존재하는 메서드의 시그니처가 바뀌어 예상치 못한 오류를 발생시킬 수도 있으므로 이를 인지하고 사용하
    MyExample().printMessage("확장 출력")
     */
    var myExample: MyExample? = null
    myExample.printNullOrNotNull() //null 안전 연산자를 쓰지 않았는데도 컴파일 오류가 안났다 -> 내부에서 null 처리코드가 구현되어 있기 때문에 컴파일 오류가 발생하지 않는다

    myExample = MyExample()
    myExample.printNullOrNotNull()
}
  • 코틀린은 클래스를 상속하거나 데코레이터 패턴과 같은 디자인 패턴을 사용하지 않고도 클래스를 확장할 수 있는 기능을 제공
    • 확장 함수 내부의 this는 확장의 대상이 되는 객체 참조다(이런 this를 수신자 객체, 리시버라 한다)
  • 자바로 변환된 확장 함수는 대상 객체를 수정하는 것이 아닌 내부적으로 static 메서드를 만든다.
    • 첫 번째 인자로 확장 대상 객체를 사용
  • 확장하려는 클래스에 동일한 명칭의 함수가 존재할 경우 클래스의 멤버 함수가 우선된다.
    • 함수의 시그니처가 다른 경우 문제없이 확장 기능을 사용할 수 있다.
  • null인 경우 내부에서 this == null 과 같은 형태로 null 검사를 수행할 수 있으며, 이렇게 처리하면 널 안정성 체크 필요 없이 호출할 수 있다.
728x90

'실무 프로젝트로 배우는 Kotlin & Spring > 코틀린 고급' 카테고리의 다른 글

지연 초기화  (0) 2022.10.16
제네릭  (0) 2022.10.16
실드 클래스  (0) 2022.10.09
싱글톤과 동반객체  (0) 2022.10.09
데이터 클래스  (0) 2022.10.08