Intro

기존 자바 라이브러리와 코틀린 코드를 자연스럽게 통합하는 것은 코틀린의 핵심 목표 중 하나다.

코틀린은 확장 함수와 프로퍼티를 지원하여 기존 자바 API를 재작성하지 않고도 코틀린이 해당 기능을 사용할 수 있게 해준다.

정의/특징

1. 확장 함수(Extension Function)

확장 함수는 어떤 클래스의 멤버 메서드인 것처럼 호출할 수 있지만 그 클래스의 밖에 선언된 함수다. 확장 함수를 만들려면 추가하려는 함수 이름 앞에 그 함수가 확장할 클래스의 이름을 덧붙이기만 하면 된다.

클래스 이름 = 수신 객체 타입(receiver type)

확장 함수가 호출되는 대상이 되는 값(객체) = 수신 객체(receiver object)

fun String.midChar() = this.get(this.length / 2)
// 'String' = 객체 타입   'this' = 수신 객체

println("my text".midChar())

자바 클래스로 컴파일한 클래스 파일이 있는 한 그 클래스에 원하는 대로 확장을 추가할 수 있다. (Java, Kotlin, Groovy)

<aside> 💡 수신 객체의 프로퍼티와 메서드 사용

확장 함수 내부에서는 일반적인 인스턴스 메서드의 내부에서와 마찬가지로 수신 객체의 메서드나 프로퍼티를 바로 사용할 수 있다.

단, 클래스 안에서 정의한 메서드와 달리 확장 함수 안에서는 클래스 내부에서만 사용할 수 있는 private, protected 멤버를 사용할 수 없다.

</aside>

내부 구현

확장 함수는 어떻게 구현되는지 디컴파일 후, 자바 코드로 변환해보자.

// testFunction.kt

package testPackage

fun String.midChar() = this.get(this.length / 2)

// Decompile to Java

public final class TestFunctionKt {
   public static final char midChar(@NotNull String $this$midChar) {
      Intrinsics.checkNotNullParameter($this$midChar, "$this$midChar");
      return $this$midChar.charAt($this$midChar.length() / 2);
   }
}

확장 함수는 수신 객체의 외부에, 확장 함수가 선언된 파일 이름을 클래스 명으로 하는 클래스에 선언된다. 정적 메서드로 선언이 되고, 수신 객체를 첫번째 인자로 받는다.

⇒ 즉, 확장 함수는 단지 정적 메서드 호출에 대한 문법적인 편의일 뿐이다.

자바에서 확장 함수 호출

앞서 내부 구현 코드에서 엿보았듯이 새로운 클래스 안에 확장 함수가 선언되므로 일반적인 클래스 내부 메서드를 호출하는 것과 동일한 방법으로 호출할 수 있다.

char c = TestFunctionKt.midChar("Java");

확장 함수 오버라이드?