코틀린은 자바와 100% 호환을 목표로 한다. 이를 어떻게할까 생각하다 내린 결론은 어떤 클래스 안에 있는 메소드처럼 호출할 수 있지만, 함수는 밖에 만들 수 있게 하자!
라는 개념이 나왔다. 이게 확장함수이다.
fun main() {
val str = "ABC"
println(str.lastChar())
}
fun String.lastChar(): Char {
return this[this.length-1]
}
fun 확장하려는클래스.함수이름(파라미터):리턴타입 {
// this 를 이용하여 실제 클래스 안의 값에 접근
}
위와 같이 String에 멤버함수가 생겼다.
확장함수가 public 이고, 확장함수에서 수신객체클래스의 private 혹은 protected 함수를 가져오면 캡슐화가 깨지기때문에 private 혹은 protected 가 불가능하다.
class Person() {
// 멤버함수
fun nextYearAge() {
...
}
}
// 확장함수
fun Person.nextYearAge() {
...
}
위와 같은 경우 오류가 발생하지않고 확장함수가 아닌 멤버함수가 우선 호출되므로 주의해야한다!
open class Train()
class Srt : Train()
fun Train.isTrain(): Boolean { }
fun Srt.isTrain(): Boolean { }
위 경우 선언된 타입에 따라 그에 맞는 확장함수를 가져온다
val train: Train = Train() // Train 확장함수
val srt: Train = Srt() // Train 확장함수
val srt2: Srt = Srt() // Srt 확장함수
정적 메서드를 부르는 것 처럼 사용이 가능하다 !
// kotlin
fun String.lastChar(): Char {
return this[this.length-1]
}
코틀린에서 위와 같은 확장함수가 있다면
// java
StringUtilsKt.lastChar()
이렇게 사용가능하다.
fun String.lastChar(): Char {
return this[this.length - 1]
}
val String.lastChar: Char
get() = this[this.length - 1]
확장 프로퍼티의 원리는 확장함수 + custom getter 와 동일
fun Int.add(other: Int): Int {
return this + other
}
infix fun Int.add(other: Int): Int {
return this + other
}
위 경우 기본적으로 문법이 3.add(4)
인데 infix
를 붙여 중위함수로 변경될 경우 3.add(4)
혹은 3 add 4
로 사용가능하다.
함수가 호출되는 대신 함수를 호출한 지점에 함수 본문을 그대로 복붙하고 싶은 경우 사용된다.
fun main() {
3.add(4)
}
inline fun Int.add(other: Int): Int {
return this + other
}
위와 같이 inline 을 쓰는 경우 해당 함수를 호출하게 된다면
val sum = 3.add(4)
val sum = $this$add$iv + other$iv
위와 같이 로직 자체가 복사 붙여넣기가 된다.
함수를 파라미터로 전달할 때에 오버헤드를 줄일 수 있기 때문이다.
👏 TIP : inline 함수의 사용은 성능 측정과 함께 신중하게 사용되어야 한다.
함수안에 함수를 선언하는 것을 지역함수라 한다.
fun create() {
fun valid() {
...
}
}
depth 가 깊어지고 코드가 깔끔하지도 않아 추천하지 않는다.