1. 확장 함수란?
코틀린에서 확장 함수(Extension Function)는 기존 클래스에 새로운 메서드를 추가하는 것처럼 사용할 수 있는 기능입니다. 기존 클래스를 수정하거나 상속하지 않고도 원하는 기능을 추가할 수 있어 코드의 가독성과 재사용성을 높여줍니다.
확장 함수는 클래스의 인스턴스를 첫 번째 매개변수로 받으며, 해당 인스턴스를 통해 메서드를 호출하는 것처럼 사용할 수 있습니다.
fun String.addPrefix(prefix: String): String {
return "$prefix$this"
}
fun main() {
val original = "world"
println(original.addPrefix("Hello, ")) // 출력: Hello, world
}
위 코드에서 String 클래스에 addPrefix라는 새로운 메서드를 추가한 것처럼 사용했습니다.
2. 확장 함수 사용 방법
2.1 확장 함수 선언
확장 함수는 다음과 같은 형식으로 선언합니다:
fun 클래스이름.함수이름(매개변수): 반환타입 {
// 함수 내용
}
예시:
fun Int.square(): Int {
return this * this
}
fun main() {
val number = 4
println(number.square()) // 출력: 16
}
2.2 확장 프로퍼티
확장 함수뿐만 아니라 확장 프로퍼티도 선언할 수 있습니다. 확장 프로퍼티는 새로운 프로퍼티를 추가하는 것처럼 사용할 수 있습니다.
val String.firstChar: Char
get() = this[0]
fun main() {
val text = "Kotlin"
println(text.firstChar) // 출력: K
}
2.3 Nullable 타입 확장 함수
확장 함수는 Nullable 타입에 대해서도 선언할 수 있습니다.
fun String?.isNullOrEmpty(): Boolean {
return this == null || this.isEmpty()
}
fun main() {
val text: String? = null
println(text.isNullOrEmpty()) // 출력: true
}
2.4 제네릭 확장 함수
제네릭 타입을 사용하여 확장 함수를 정의할 수 있습니다.
fun <T> List<T>.secondOrNull(): T? {
return if (this.size > 1) this[1] else null
}
fun main() {
val numbers = listOf(1, 2, 3)
println(numbers.secondOrNull()) // 출력: 2
}
3. 확장 함수의 장점
- 코드 가독성 향상: 확장 함수를 사용하면 코드가 더욱 직관적으로 보입니다.
- 기존 클래스 수정 없이 기능 추가 가능: 상속이나 데코레이터 패턴을 사용할 필요 없이 기존 클래스에 메서드를 추가할 수 있습니다.
- 유틸리티 함수 작성에 유용: 여러 클래스에 공통적으로 필요한 기능을 확장 함수로 작성하여 재사용성을 높일 수 있습니다.
4. 확장 함수의 단점과 주의점
- 우선순위 문제: 확장 함수와 클래스 내부에 같은 이름의 메서드가 있을 경우 클래스 내부 메서드가 우선적으로 호출됩니다.
class Sample { fun show() = println("Class method") } fun Sample.show() = println("Extension function") fun main() { val sample = Sample() sample.show() // 출력: Class method }
- 오버라이드 불가: 확장 함수는 클래스 내부에 정의된 메서드가 아니므로 오버라이드할 수 없습니다.
- 캡슐화 위반 가능성: 확장 함수는 클래스의 private 또는 protected 멤버에 접근할 수 없습니다.
5. 현업 주요 사용 예시
5.1 컬렉션에 확장 함수 추가
fun List<Int>.sumOfSquares(): Int {
return this.sumOf { it * it }
}
fun main() {
val numbers = listOf(1, 2, 3, 4)
println(numbers.sumOfSquares()) // 출력: 30
}
5.2 문자열 관련 확장 함수
fun String.capitalizeWords(): String {
return this.split(" ").joinToString(" ") { it.capitalize() }
}
fun main() {
val text = "hello kotlin world"
println(text.capitalizeWords()) // 출력: Hello Kotlin World
}
5.3 Nullable 타입 처리 확장 함수
fun String?.safeLength(): Int {
return this?.length ?: 0
}
fun main() {
val nullableText: String? = null
println(nullableText.safeLength()) // 출력: 0
}
6. 확장 함수와 고차 함수의 조합
고차 함수는 다른 함수를 매개변수로 받거나 반환할 수 있는 함수입니다. 확장 함수와 고차 함수를 결합하면 더 유연하고 재사용 가능한 코드를 작성할 수 있습니다.
예를 들어, 다음 코드는 리스트의 각 요소와 해당 인덱스를 함께 처리할 수 있는 확장 함수를 정의합니다:
fun <T> List<T>.forEachWithIndex(action: (index: Int, T) -> Unit) {
for (i in this.indices) {
action(i, this[i])
}
}
fun main() {
val items = listOf("a", "b", "c")
items.forEachWithIndex { index, value ->
println("$index: $value")
}
}
코틀린 확장 함수는 코드를 더 간결하고 읽기 쉽게 만들어주며, 기존 클래스에 기능을 추가할 수 있는 강력한 도구입니다. 하지만 우선순위 문제나 오버라이드 불가와 같은 단점을 이해하고 적절하게 사용하는 것이 중요합니다.
추가자료) 안드로이드 앱 개발 시 적용하면 유용한 확장 함수 예시
안드로이드 프로그래밍에서 확장 함수를 적용하면 코드 가독성을 향상시키고 유지보수하기 편하게 관리할 수 있는 경우들이 있습니다. 아래 포스팅에 해당 내용 자세히 정리했습니다.
2025.01.15 - [안드로이드] - [안드로이드] 현업에서 유용한 코틀린 확장함수(extension function) 예시 총 정리
댓글