티스토리 뷰

반응형

확장 함수

  확장 함수(extension function)는 클래스 밖에 선언되었지만 클래스의 멤버 메서드처럼 호출할 수 있는 함수이다.

 

fun String.lastChar(): Char = this.get(this.length - 1)

  위 함수는 마지막 문자열을 돌려주는 확장 함수의 예시이다. 확장 함수 작성시 함수가 어떤 클래스 것인지 receiver type을 지정해 주어야한다. 코드에서는 lastChar 앞에 있는 String이 receiver type이 된다. receiver object는 호출되는 대상이다. 코드에서 this가 이에 해당한다.

 

"kotlin".lastChar()

  lastChar 함수는 위와 같이 사용할 수 있다. lastChar은 String 클래스 안에 작성되지는 않았지만 String 메서드이다. 

 

fun String.lastChar(): Char = get(length - 1)

  receiver object의 메서드와 프로퍼티를 바로 사용가능하기 때문에 메서드에서 this를 생략 가능하듯 확장 함수에서도 this는 생략 가능하다. 하지만, private 혹은 protected 접근 지정자를 가진 멤버는 사용 불가능하다.

 

 

Java에서 확장함수 호출

ExtensionFunctionKt.lastChar("kotlin");

  확장함수를 ExtensionFunction.kt라는 코틀린 파일에 정의했다면 ExtensionFunctionKt.함수명으로 확장함수를 호출할 수 있다. 코틀린과 달리 자바에서 호출을 한다면 첫 번째 인자로 receiver object를 넘겨야 한다. (위 코드에서 "kotlin"에 해당)

 

 

확장 함수 활용 - 유틸리티 함수

fun <T> joinToString(
  collection: Collection<T>,
  separator: String,
  prefix: String,
  postfix: String
): String {
  val result = StringBuilder(prefix)

  for ((index, element) in collection.withIndex()) {
    if(index > 0) result.append(separator)
    result.append(element)
  }

  result.append(postfix)
  return result.toString()
}

  위의 함수를 아래와 같은 확장 함수로 변경할 수 있다.

 

fun <T> Collection<T>.joinToString(
  separator: String = ", ",
  prefix: String = "",
  postfix: String = ""
): String {
  val result = StringBuilder(prefix)

  for((index, element) in this.withIndex()) {
    if (index > 0) result.append(separator)
    result.append(element)
  }
  
  result.append(postfix)
  return result.toString()
}

 

 

확장함수 - 오버라이드 불가능

 

  확장함수는 오버라이드 불가능하다. 확장함수는 클래스 밖에 선언되고 클래스의 일부가 아니다. 실제로 확장 함수를 호출 할 때 동적타입이 아닌 정적 타입에 의해 호출되는 확장함수가 결정된다.

 

open class Parent {
}

class Child : Parent() {
}

fun Parent.print() = println("Parent Class")
fun Child.print() = println("Child Class")

fun main() {
  val obj: Parent = Child()
  obj.print()
}
Parent Class

  위의 코드를 실행시 print를 호출에서 Child 확장함수 print가 아닌 Parent 확장함수 print가 호출되는 것을 알 수 있다. 코틀린이 호출될 확장함수를 정적으로 결정하는 것을 알 수 있다.

 

 

확장 프로퍼티

  확장 프로퍼티를 사용하면 프로퍼티 형식으로 사용가능한 API를 추가할 수 있다. 프로퍼티 문법을 사용했기 때문에 코드를 더 짧게 작성할 수 있다는 장점이 있다. 확장 프로퍼티는 상태를 저장할 방법이 없기 때문에 아무 상태도 가지지 않는다.

 

val String.lastChar: Char
  get() = get(length - 1)

  문자열에서 맨 마지막 문자를 가져오는 확장 프로퍼티이다. 일반적인 프로퍼티에서 receiver type이 추가된 모습이다. 상태를 저장할 수 없기 때문에 getter을 꼭 정의해야 하고 초기화 코드도 사용이 불가능하다.

 

println("kotlin".lastChar)

  확장 프로퍼티도 다른 프로퍼티와 같이 사용하면 된다.

 

 

참고 자료

  • Kotlin IN ACTION
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함