더북(TheBook)

다음 함수 정의를 살펴보자.

fun mul(a: Int, b: Int) = a*b            // 1
fun mul(a: Int, b: Int, c: Int) = a*b*c  // 2
fun mul(s: String, n: Int) = s.repeat(n) // 3
fun mul(o: Any, n: Int) = Array(n) { o } // 4

다음은 몇 가지 함수 호출의 오버로딩을 해결한 결과다.

mul(1, 2)   // Int가 Any의 하위 타입이므로 1과 4 중에 1을 선택
mul(1, 2L)  // error: none of the following functions can be called with the arguments supplied
            // 오류: (Int, Long) 타입을 받을 수 있는 함수가 없음
mul(1L, 2)  // Long, Int 타입을 받을 수 있는 함수는 4번뿐이므로 4를 선택
mul("0", 3) // String이 Any의 하위 타입이기 때문에 3과 4 중에 3을 선택

덜 구체적인 함수로 간주될 것 같은 함수를 호출하고 싶은 경우에는 다음 코드처럼 as 타입 캐스팅(type casting) 연산자를 사용해 인자를 상위 타입으로 명시적으로 변환해야 한다.

mul("0" as Any, 3) // (Any, Int)를 받을 수 있는 함수는 4뿐이므로 4를 선택

as 연산은 8장 클래스 계층 이해하기에서 살펴본다. 8장에서는 코틀린의 하위 타입 관계와 상속을 자세히 다룰 것이다.

자바에서는 오버로딩한 메서드들이 똑같은 연산을 수행하는데, 사용자가 함수 인자 중 일부를 생략해 미리 정해진 디폴트 값을 사용할 수 있게 하고자 메서드를 오버로딩해야 하는 경우가 있다. 이번 절 맨 앞에서 정의한 readInt() 함수를 살펴보라. 두 함수 모두 입력 문자열을 정수로 변환하는데 첫 번째 함수는 10진법으로 문자열을 파싱하지만, 두 번째 함수는 다양한 진법으로 문자열을 파싱한다는 점만 다르다. 실제로 다음과 같이 두 번째 함수를 사용해 첫 번째 함수를 작성할 수도 있다.

fun readInt() = readInt(10)
신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.