밤빵's 개발일지
[TIL]20241031 Operator Overloading 본문
코틀린의 연산자 오버로딩(Operator Overloading)은 객체 간의 연산을 정의해 코드가 더 직관적이고 간결해지도록 도와주는 기능이다. 자바에서는 연산자를 직접 오버로딩할 수 없지만, 코틀린에서는 다양한 연산자(+, -, *, /, % 등)를 클래스에 맞게 재정의할 수 있다.
▶ 연산자 오버로딩 (Operator Overloading)
연산자 오버로딩은 특정 클래스에 연산자를 재정의하여 그 클래스에 맞는 연산 방식을 구현하는 방법이다. 예를 들어, 두 객체를 더하는 + 연산자를 재정의하면 객체1 + 객체2 형식으로 직관적인 코드를 작성할 수 있다. 이 기능은 특히 벡터, 복소수, 행렬 등의 수학적 개념을 다룰 때 유용하다. 자바에서는 연산자 오버로딩을 지원하지 않지만, 코틀린에서는 이러한 기능을 통해 수학적 표현을 객체 간의 연산으로 쉽게 구현할 수 있다.
▶코틀린에서의 연산자 오버로딩 규칙
코틀린에서 연산자 오버로딩을 사용하기 위해서는 연산자 함수를 정의해야 하고, 이때 함수 이름 앞에 operator 키워드를 추가해야 한다. 이는 해당 함수가 연산자 오버로딩용 함수임을 컴파일러가 인식하도록 해준다. 또한, 코틀린에서 오버로딩 가능한 연산자는 정해져 있으며, 모든 연산자를 오버로딩할 수 있는 것은 아니다.
▷ 오버로딩 가능한 주요 연산자
- +: plus 함수
- -: minus 함수
- *: times 함수
- /: div 함수
- %: rem 함수
- ==: equals 함수
- <, >, <=, >=: compareTo 함수
▶ Point 클래스에 연산자 오버로딩 적용하기
좌표를 나타내는 Point 클래스에 +와 - 연산자를 오버로딩하여 두 Point 객체를 더하고 뺄 수 있도록 구현한 예시이다.
data class Point(val x: Int, val y: Int) {
// + 연산자 오버로딩
operator fun plus(other: Point): Point {
return Point(x + other.x, y + other.y)
}
// - 연산자 오버로딩
operator fun minus(other: Point): Point {
return Point(x - other.x, y - other.y)
}
}
fun main() {
val point1 = Point(3, 5)
val point2 = Point(2, 4)
val sum = point1 + point2 // Point(x=5, y=9)
val difference = point1 - point2 // Point(x=1, y=1)
println("Sum: $sum")
println("Difference: $difference")
}
→ Point 클래스에서 plus와 minus 함수를 오버로딩하여 +와 - 연산자를 정의했다.
→ operator 키워드를 사용하여 +와 - 연산자가 plus와 minus 함수와 연결되도록 했다.
→ 이로 인해 point1 + point2와 같은 직관적인 코드를 작성할 수 있고, 이는 실제로 point1.plus(point2)를 호출하는 것과 동일하다.
▶ 자바와의 차이점
자바에서는 기본 연산자를 오버로딩할 수 없기 때문에, 연산자 오버로딩을 사용하려면 메서드를 명시적으로 호출해야 한다. 예를 들어, point1.add(point2) 형식으로 호출하는 반면, 코틀린에서는 +, -와 같은 연산자를 직접 오버로딩하여 point1 + point2 형식으로 더욱 직관적인 코드 작성을 가능하게 한다. 이는 코틀린이 표현력 높은 코드를 작성할 수 있게 해주는 중요한 차별점 중 하나이다.
▶ 복소수 클래스에 연산자 오버로딩 적용하기
연산자 오버로딩은 벡터나 좌표뿐만 아니라 복소수와 같은 수학적 개념에서도 유용하게 활용할 수 있다. 아래는 ComplexNumber 클래스에서 +, - 연산자를 오버로딩한 예시이다.
data class ComplexNumber(val real: Double, val imaginary: Double) {
operator fun plus(other: ComplexNumber): ComplexNumber {
return ComplexNumber(real + other.real, imaginary + other.imaginary)
}
operator fun minus(other: ComplexNumber): ComplexNumber {
return ComplexNumber(real - other.real, imaginary - other.imaginary)
}
}
fun main() {
val num1 = ComplexNumber(3.0, 4.0)
val num2 = ComplexNumber(1.0, 2.0)
val sum = num1 + num2 // ComplexNumber(real=4.0, imaginary=6.0)
val difference = num1 - num2 // ComplexNumber(real=2.0, imaginary=2.0)
println("Sum: $sum")
println("Difference: $difference")
}
→ ComplexNumber 클래스에서 plus와 minus 함수를 오버로딩하여 복소수의 덧셈과 뺄셈을 표현할 수 있다.
→ 이로 인해 num1 + num2처럼 간결하고 직관적인 방식으로 복소수 연산을 수행할 수 있다.
▶연산자 오버로딩의 장점
코드 가독성 향상
plus나 minus 메서드를 직접 호출하는 것보다 +, -와 같은 연산자를 사용하는 것이 더 직관적이고 읽기 쉬운 코드를 만들어 준다.
직관적인 표현
객체 간의 연산을 수학적 표현처럼 작성할 수 있어 코드가 간결해진다.
유연한 구현
특정 클래스에 맞는 연산자 동작을 커스터마이징할 수 있어, 사용자의 요구에 맞게 연산 동작을 정의할 수 있다.
▶오버로딩 시 주의사항
남용 주의
연산자 오버로딩은 코드의 가독성을 높여주지만, 무분별하게 사용하면 오히려 코드의 의미가 모호해질 수 있다. 특히, 연산자의 기본 의미와 다른 기능을 구현하면 코드의 직관성을 해칠 수 있으므로 주의해야 한다.
연산자 우선순위
연산자 오버로딩은 일반적인 연산자 우선순위를 따르기 때문에, 복잡한 연산을 할 때는 괄호를 사용하여 우선순위를 명시하는 것이 좋다.
코틀린의 연산자 오버로딩은 코드의 직관성과 가독성을 높여주는 유용한 기능이다. 특히 수학적 연산이나 데이터 처리에서 객체 간의 연산을 보다 자연스럽고 간단하게 구현할 수 있도록 돕는다. 자바와 달리 코틀린에서는 연산자 오버로딩을 통해 객체 간 연산을 사용자 정의 메서드로 처리할 수 있어 유연한 코드 작성이 가능하다.
'Kotlin' 카테고리의 다른 글
[TIL]20241102 백틱(`) 활용 (0) | 2024.11.02 |
---|---|
[TIL]20241101 타입 시스템 (0) | 2024.11.01 |
[TIL]20241030 try-with-resources & use (4) | 2024.10.30 |
[TIL]20241029 Nested Functions (3) | 2024.10.29 |
[TIL]20241028 by 와 Delegation (1) | 2024.10.28 |