1. 오버로딩
오버로딩(Overloading)은 동일한 이름의 함수를 파라미터 목록에 따라 여러 형태로 정의할 수 있게 하는 프로그래밍 기능입니다.
코틀린에서는 오버로딩을 어떤식으로 사용할까요?
fun main() {
val over = Overloading()
val num1 = over.f()
val num2 = over.f(2)
println(num1) // 0 출력
println(num2) // 3 출력
}
class Overloading {
fun f() = 0
fun f(n: Int) = n + 1
}
함수의 시그니처는 함수 이름, 파라미터 목록, 반환 타입으로 이뤄집니다. 코틀린은 시그니처를 비교해 함수를 구분하게 되는데
이 때 함수를 오버로딩할 때에는 파라미터를 서로 다르게 만들어야합니다.
(반환 타입은 오버로딩 대상이 아님)
1-1 확장 함수와 시그니처가 같은 멤버함수가 있는 경우
어떤 클래스 안에 확장 함수와 시그니처가 똑같은 멤버함수가 있다면 어떤 결과가 일어날까요?
fun main() {
val over = Overloading().f()
println(over) // 0 출력
}
class Overloading {
fun f() = 0 //멤버함수
fun f(n: Int) = n + 1
}
fun Overloading.f() = 1 //확장 함수
코틀린은 클래스 안에 확장 함수와 시그니처가 똑같은 멤버함수가 존재하면 멤버 함수를 우선하게 됩니다.
확장 함수를 정의할 때는 멤버 함수와의 충돌 가능성을 고려해야 하며, 필요하다면 함수 이름을 변경하거나 확장 함수 사용을 지양해야 합니다.
1-2 디폴트 인자와 함수 오버로딩을 함께 사용하는 경우
fun default(n: Int = 99) = println("default: $n")
fun default() {
println("default")
}
fun main() {
default() //default 출력
}
오버로딩과 디폴트 인자를 함께 사용하는 경우에는 함수 시그니처와 함수 호출이 가장 가깝게 일치되는 함수를 호출하게 됩니다. 파라미터가 없는 default() 함수를 호출했기 때문에 디폴트인자를 사용해 함수를 호출하지 않고 파라미터가 없는 두 번째 default 함수를 호출하게 됩니다.
1-3 오버로딩이 유용한 이유
오버로딩을 활용하면 함수 이름을 하나로 통일하면서 다양한 데이터 타입에 따라 다르게 동작하도록 구현할 수 있습니다. 이는 데이터 타입에 따라 다른 이름을 정의할 필요를 없애고, 함수 호출의 일관성을 제공합니다.
fun printValue(value: Int) = println("Int: $value")
fun printValue(value: String) = println("String: $value")
fun printValue(value: Double) = println("Double: $value")
(동일한 개념을 기반으로 하는 다양한 연산을 하나의 함수 이름으로 통합할 수 있다)
- 재사용성 증가: 동일한 이름으로 다양한 파라미터나 동작 정의 가능
- 가독성 향상: 함수 호출의 일관성 제공
- 유연성 강화: 타입에 따라 다른 동작 처리
2. when 식
when (비교대상) {
일치할 수 있는 대상 -> ~~~
일치할 수 있는 대상 -> ~~~
}
fun main() {
val a = 1
when (a) {
1 -> println("나는 1이다") //출력
2 -> println("나는 2이다")
3 -> println("나는 3이다")
else -> println("나는 아무것도 아니다")
}
}
- when 식은 a를 본문의 match 식과 비교한다
- 일치하는 match식에서 when 식의 실행이 끝난다.
- else는 일치하는 매치식이 없을 경우 대안으로 사용할 식을 제공한다.
2-1 when과 else
위의 예제의 경우 반환값이 없는 단순 출력문이기 때문에 else문이 생략이 가능하지만 반환값이 존재하는 경우 else가 존재하지 않으면 컴파일 에러가 발생하게 됩니다.
fun f(month: String): String {
return when(month) {
"November" -> "11월~~"
"December" -> "12월~~"
}
}
2-2 범위 검색
in을 사용해 값이 특정 범위에 속하는지 확인할 수 있습니다.
fun getHttpStatusMessage(statusCode: Int): String {
return when (statusCode) {
in 200..299 -> "성공"
in 400..499 -> "클라이언트 오류"
in 500..599 -> "서버 오류"
else -> "알 수 없는 상태 코드"
}
}
fun main() {
val statusCode = 200
val status = getHttpStatusMessage(statusCode)
println(status) //성공 출력
}
2-3 표현식으로 사용하기
when은 값 반환이 가능하며 표현식으로도 이용할 수 있습니다.
fun main() {
val weather = "Winter"
val result = when (weather) {
"Spring" -> "봄봄봄"
"Summer" -> "여름여름"
"Fall" -> "가을가을"
else -> "겨울겨울"
}
println(result) //겨울겨울 출력
}
3. 총정리
오버로딩
- 동일한 함수 이름으로 다양한 동작 정의 가능
- 확장 함수와 멤버 함수의 우선순위 충돌 주의
when 식
- 조건문 대체 가능 표현식 및 타입 검사, 범위 검사를 지원
- else는 반환 값이 있는 경우 필수
- 분기처리를 통해 세부 동작을 정의할 수 있음
'Kotlin 정리' 카테고리의 다른 글
[Kotlin 공부 8일차] 널이 될 수 있는 타입 (0) | 2024.12.12 |
---|---|
[Kotlin 공부 7일차] 데이터 클래스, 구조 분해 선언 (0) | 2024.12.10 |
[Kotlin 공부 5일차] 확장 함수, 이름 붙은 인자와 디폴트 인자 (0) | 2024.12.04 |
[Kotlin 공부 4일차] 객체, 클래스, 생성자 (0) | 2024.12.02 |
[Kotlin 공부 3일차] 루프와 범위 (0) | 2024.11.29 |