Kotlin (6) 확장 함수

벌써 여섯 번째 시간이다.

오늘은 코틀린에서 사용되는 확장 함수, 중첩 함수에 관하려 공부하는 시간을 가져보려고 한다.

이후에 나오는 코드들은 Kotlin Playground에서 직접 입력하고, 실행하며 학습하면 도움이 된다!

바로 본론으로 넘어가겠다.

Kotlin

☝ 확장 함수

확장이란, 이미 존재하는 클래스를 상속하거나 하지 않아도 새로운 기능을 갖는 클래스로 확장 시킬 수 있는 기능이다.

확장 함수는, 해당 클래스명을 포함하는 패키지를 호출한 후,className.function()의 꼴로 정의할 수 있다.

아래 예시를 통해 살펴보자.

Kotlin

package ints

fun main() {
   fun Int.goTheBlue(): Int{
        return this * 2
    }
    
    print(10.goTheBlue())
}

Result

20

int에 더블로 가는 함수를 만들어보았다.

해당 형식의 끝에 .functionName()을 호출하는 것 만으로 내가 만든 함수를 내장 함수처럼 사용할 수 있게 되었다.

이렇게 내가 정의한 확장 함수를 다른 소스에서 호출하고 싶을 때는 클래스의 함수명까지 명시적으로 import하여야 한다.

아래 예시를 통해 이해해보자.

Kotlin

// 위의 코드와 다른 소스 파일
import ints.goTheBlue as ironDragon

print(20.ironDragon())

Result

40

goTheBlue()함수를 ironDragon()으로 이름을 변경하여 호출해주었다.

확장 함수를 import할 때 함수 이름이 중복되는 경우 이 방법을 통해 이름을 치환하여 오류를 방지할 수 있다.

1.1 확장함수의 override

Kotlin

open class Korea {
	//....
}

class Jeju: Korea() {
    override fun bye() = println("또시꼭옵서양")   
}

fun main() {
    fun Korea.bye() { println("안녕히계세요.") }
}

Result

OpenJDK 64-Bit Server VM warning: Options -Xverify:none and -noverify were deprecated in JDK 13 and will likely be removed in a future release.
Main.kt:5:5: error: 'bye' overrides nothing
    override fun bye() = println("또시꼭옵서양")   

확장함수는 override가 허용되지 않는다.

클래스 밖에서 선언된 함수이기 때문에, override 자체가 성립하지 않기 때문이다.

참고로, open class란 상속을 허용하는 클래스를 의미한다. open을 명시하지 않을 시, Java의 final 클래스와 동일한 취급을 받는다.

  • Java -> 상속 불가능한 클래스를 final을 통해 지정.
  • Kotlin -> 상속 가능한 클래스를 open을 통해 지정.

1.2 확장 함수 간 우선 순위

Kotlin

open class Korea {
}

class Jeju: Korea() {
}

fun main() {
    fun Korea.hello() = println("안녕하세요.")
    fun Jeju.hello() = println("안녕하우꽈.")
    
    val korea: Korea = Jeju()
    korea.hello()
}

Result

안녕하세요.

상속받는 클래스 간 확장함수가 중복되는 경우이다.

korea에는 Jeju()가 들어있지만, Korea로 정의된 값이므로 Korea에 정의된 확장 함수가 호출된다.

Kotlin

class Tazza() {
    fun heSaid() = "내가 빙다리 핫바지로 뵈냐"
}

fun main() {
    fun Tazza.heSaid() ="사쿠라네? 사쿠라여?"
    
    val tazza: Tazza = Tazza()
    
    println(tazza.heSaid())
}

Result

내가 빙다리 핫바지로 뵈냐

또한, 이미 특정 클래스에 확장 함수와 같은 멤버 변수가 존재한다면 확장 함수의 정의는 무시된다.

즉, 멤버 변수가 확장 함수보다 높은 우선 순위를 갖는다.

🤞 중첩 함수

Kotlin

class Person(val name: String, val age: Int)

fun main() {
    fun introduce(people: List<Person>) {
        fun said() {
            for (person in people) {
                println("hello, my name is ${person.name}, and I'm ${person.age} nice to meet you.")
            }
        }
        said()
    }
    
    var people: List<Person> = listOf(Person("ByeongJin",27),Person("Hyerim",23),Person("Minsu",25),Person("Donggi",25),Person("Yunjin",26))
    introduce(people)
}

Result

hello, my name is ByeongJin, and I'm 27 nice to meet you.
hello, my name is Hyerim, and I'm 23 nice to meet you.
hello, my name is Minsu, and I'm 25 nice to meet you.
hello, my name is Donggi, and I'm 25 nice to meet you.
hello, my name is Yunjin, and I'm 26 nice to meet you.

중첩 함수는, 함수 안에 들어있는 함수를 의미한다.

특정 함수 안에서만 사용되는 함수가 많아질 때, 중첩 함수를 통해 코드를 간소화 시키면 코드 가독성이 높아진다.

또한, 중첩 함수는 외부 함수의 모든 파라미터나 변수에 자유롭게 접근 가능하다는 장점이 존재한다.

태그:

카테고리:

업데이트:

댓글남기기