Kotlin in Action 이어서 연산자 오버로딩!
코틀린에서 관례를 사용하는 가장 대표적인 예.
자바에서는 원시타입과 String 타입만 + 연산자를 쓸 수 있다.
하지만 코틀린에선 좀 더 넓은 범위에서 오버로딩을 통해 사용할 수 있다.
연산자를 오버로딩하는 함수 앞에는 항상 operator
를 붙여야 한다.
operator 변경자로 plus 함수를 선언하면 +
로 plus를 할 수 있다.
a+b -> a.plus(b)
확장함수로도 오버로딩 구현이 가능하다.
data class Point(val x: Int, val y: Int) {
operator fun plus(other: Point) : Point {
return Point(x+other.x, y+other.y)
}
}
fun main() {
val p1 = Point(10,20)
val p2 = Point(30,40)
println(p1+p2)
}
식 | 함수 이름 |
---|---|
a * b | times |
a / b | div |
a % b | mod(1.1부터 rem) |
a + b | plus |
a - b | minus |
직접 정의한 함수로 구현해도 연산자 우선순위는 숫자 연산과 같다. (*,/,% > +,-)
두 피연산자의 타입이 달라도 구현만 신경써서 해두면 상관없고, return 타입이 피연산자 타입과 달라도 괜찮다.
plus 같은 연산자를 오버로딩하면 + 뿐만아니라 관련 복합 대입 연산자인
+=
도 함께 지원한다.
var p3 = Point(100,200)
p3 += Point(300,400)
println(p3) // Point(x=400, y=600)
val nums = ArrayList<Int>()
nums += 42
println(nums[0]) // 42
-a, b++ 같은 단항 연산자도 코틀린에선 오버로딩이 가능하다.
operator fun Point.unaryMinus() : Point {
return Point(-x,-y)
}
// ...
val p4 = Point(10,20)
println(-p4) // Point(x=-10, y=-20)
식 | 함수 이름 |
---|---|
+a | unaryPlus |
-a | unaryMinus |
!a | not |
++a, a++ | inc |
--a, a-- | dec |
코틀린은 == 연산자 호출을 equals 메서드 호출로 컴파일한다. != 연산자도 자동으로 지원된다.
a==b를 처리할 때, a가 null인지 판단해서 널이 아닌경우에만 a.equals(b)를 호출한다.
a가 null이면 b도 null이여야 true다.
a == b -----> a?.equals(b) ?: (b==null)
자바에서 최대값, 최솟값, 정렬 등 비교를 해야하는 알고리즘에서는 Comparable 인터페이스를 구현한다. compareTo는 Comparable 인터페이스에 들어있고, 한 객체와 다른객체의 크기를 비교해 정수로 나타낸다.
코틀린도 똑같은 Comparable 인터페이스를 지원한다.
비교연산자(>,<,<=,>=)는 compareTo 호출로 컴파일 된다. 반환값은 Int다.
a >= b -------> a.compareTo(b) >= 0
아래는 Compareble을 구현해 compareTo를 오버라이드한 예시이다.
compareValuesBy라는 코틀린 표준 라이브러리 함수를 사용했다.
이 함수는 두 객체를 받아들이고 뒤에 비교할 속성을 나열하는 함수이다.
class Person(val firstName: String, val lastName: String) : Comparable<Person> {
override fun compareTo(other: Person): Int {
return compareValuesBy(this, other, Person::lastName, Person::firstName)
}
//...
val person1 = Person("Kim", "KY")
val person2 = Person("Ryu", "CB")
println(person1 > person2) // true
}