오늘은 확장 함수에 대해서 공부해보았습니다.
fun List<Int>.getHigherThan(num : Int) : List<Int> {
val result = arrayListOf<Int>()
for(item in this) { // this는 자기자신(여기서는 numbers를 뜻함)
if(item > num) {
result.add(item)
}
}
return result
}
fun main() {
val numbers : List<Int> = listOf(1, 2, 3, 4, 5, 6)
val filtered = numbers.getHigherThan(3).toString()
println(filtered)
}
- 결과 -
[4, 5, 6]
확장함수 정의는 그냥 함수 작성하듯이 작성하면 되는데
자료형.함수
형식으로 작성을 하면 됩니다.
확장 함수는 내가 필요한 기능을 확장하는 기술이기 때문에 자주 쓰일것 같습니다.
// Generic 타입에 관해서도 확장이 가능하다.
fun <T> MutableList<T>.swap(index1: Int, index2: Int) {
val tmp = this[index1]
this[index1] = this[index2]
this[index2] = tmp
}
fun main() {
val testList = mutableListOf("A", "B", "C")
// swap() 함수 호출
testList.swap(0, 2)
println(testList)
}
- 결과 -
[C, B, A]
Generic 타입도 그대로 적용시켜 유연한 함수를 작성할 수 있습니다.
class NewList : ArrayList<Int>() {
fun getHigherThan(num: Int): List<Int> {
val result = arrayListOf<Int>()
this.forEach { it->
if (it > num) {
result.add(it)
}
}
return result
}
}
fun main() {
val numbers = NewList()
numbers.add(1)
numbers.add(2)
numbers.add(3)
numbers.add(4)
numbers.add(5)
numbers.add(6)
val filtered = numbers.getHigherThan(4).toString()
println(filtered)
}
- 결과 -
[5, 6]
상속을 활용하여 확장함수를 작성할수 있는데
이경우에는 확장함수 느낌보다는 그냥 클래스 함수를 선언한 느낌이 많이 강했습니다.
class Test {
fun solution(char : Char) {
println("안녕")
}
fun solution2(int : Int) {
println("반가워")
}
}
// Test 클래스 안의 멤버 함수인 solution과 이름은 같지만 매개변수 타입이 달라 구분 가능
fun Test.solution(int : Int) {
println("잘가")
}
// Test 클래스 안의 멤버 함수인 solution2와 이름도 같고 매개변수 타입도 같아 구분 불가능
fun Test.solution2(int : Int) {
println("또봐")
}
fun main() {
// 확장 함수는 멤버 함수를 오버로딩 할 수는 있다.
Test().solution('c')
Test().solution(1)
Test().solution2(3) // 확장 함수 호출되지 않고 멤버 함수가 호출.
}
- 결과 -
안녕
잘가
반가워
클래스가 가진 멤버함수와 클래스의 확장함수를 정의했을때
이름이 동일하고 매개변수가 다른 오버로딩이 가능 한것을 확인할 수가 있습니다.
하지만 멤버함수화 확장함수의 오버로딩은 기능을 분산시키는것 같아서 별로 안쓸것 같습니다. (기능의 분산으로 가독성이 떨어지는 듯)