코틀린은 자바와 100% 호환하는것을 목표로 하고있다.
그렇기 때문에 기존 자바코드 위에 자연스럽게 코틀린 코드를 추가할 수 없는지에 대해 고민하게 되었다.
자바로 만들어진 라이브러리를 유지보수 및 확장할 때 코틀린 코드를 덧붙이고 싶다는 니즈가 발생.
그래서 어떤 클래스 안에 있는 메소드처럼 호출할 수 있지만, 함수는 밖에 만들 수 있게 하자는 개념이 생김.
그것이 바로 확장함수의 개념이다.
fun String.lastChar(): Char {
return this.last()
}
fun main() {
println("abc".lastChar())
}
String Class를 확장해서 lastChar() 이라는 메소드를 추가하였다.
원래 String의 멤버함수처럼 사용이 가능하다.
여기서 this를 수신객체라 부르고, 확장하려는 클래스 타입을 수신객체 타입이라고 한다.
확장함수는 원래 클래스에 있는 private 또는 protected 멤버를 가져올 수 없다. (private이나 protected 멤버를 가져올 수 있다면 캡슐화가 깨지게 되므로)
원래의 멤버함수와 확장함수의 시그니처가 같다면?
만약 확장함수가 Override 된다면 호출 시 우선순위는 어떻게 될까?
fun main() {
val train: Train = Train()
train.isExpensive() // Train의 확장함수
val srt1: Train = Srt()
srt1.isExpensive() // Train의 확장함수
val srt2: Srt = Srt()
srt2.isExpensive() // Srt의 확장함수
}
open class Train(
val name: String = "새마을기차",
val price: Int = 5000
)
fun Train.isExpensive(): Boolean {
println("Train의 확장함수")
return this.price >= 10000
}
class Srt: Train("SRT", 40000)
fun Srt.isExpensive(): Boolean {
println("Srt의 확장함수")
return this.price >= 10000
}
자바에서는 코틀린코드의 확장 함수를 static 메소드를 사용하는 것 처럼 사용이 가능하다.
함수를 호출하는 새로운 방법이다.
fun main() {
3.add(4)
3.add2(4)
3 add2 4
}
fun Int.add(other: Int): Int {
return this + other
}
infix fun Int.add2(other: Int): Int {
return this + other
}
Inline 함수는, 함수가 호출되는 대신, 함수를 호출한 지점에 함수 본문을 그대로 복사하는 것이다.
inline fun Int.add3(other: Int): Int {
return this + other
}
왜 이런것을 사용할까?