모든 내용은 Do it! 코틀린 프로그래밍을 바탕으로 정리한 것입니다.
연산자 오버로딩
연산자 오버로딩 → 다형성
오버로딩 : 동일한 클래스 안에서 같은 이름의 메서드가 매개변수만 달리해서 여러 번 정의되는 것
Kotlin 다형성의 오버라이딩, 오버로딩에 관련된 글 확인↑
in 코틀린, 특정 연산자의 역할을 함수로 정의하고 있음 → 일종의 협약(Convention)
연산자에는 일종의 우선순위(Precedence)를 가지고 있음
연산자의 작동 방식
연산자를 사용하는 것 == 관련된 멤버 메서드를 호출하는 것
코틀린 표준 라이브러리 Primitives.kt에 보면 operator 키워드를 사용해 plus() 함수가 다양한 자료형으로 선언되어 있음
- +, - 와 같은 연산자는 기본적으로 많은 자료형을 처리하기 위해 이미 오버로딩되어 있음
- 사용자가 추가적으로 연산자를 오버로딩 할 수 있음
class Point(var x: Int = 0, var y: Int = 10) {
operator fun plus(p: Point) : Point {
return Point(x+p.x, y+p.y)
}
operator fun dec() = Point(--x, --y)
}
fun main() {
val p1 = Point(3, -8)
val p2 = Point(2, 9)
var point = Point()
point = p1+p2
println("point = (${point.x}, ${point.y})")
--point
println("point = (${point.x}, ${point.y})")
}
- Point 클래스를 만들고 +, -- 연산자 오버로딩
- 오버로딩한 + 연산자 : x, y 값을 각각 더해 새로운 객체에 할당
- 오버로딩한 -- 연산자 : x, y 값을 하나씩 줄임
연산자의 종류
산술 연산자
표현식 | 의미 |
a + b | a.plus(b) |
a - b | a.minus(b) |
a * b | a.times(b) |
a / b | a.div(b) |
a % b | a.rem(b) - Kotlin 1.1부터 지원, a.mod(b) - 지원 중단 |
a .. b | a.rangeTo(b) |
호출 연산자
호출 연산자(Invoke Operator) : 함수 호출을 돕는데 사용
class Manager {
operator fun invoke(value: String) {
println(value)
}
}
fun main() {
val manager = Manager()
manager("Do something for me!")
val sum = {x: Int, y: Int -> x+y}
val result1 = sum.invoke(3, 10)
val result2 = sum(3, 10)
println("${result1}, ${result2}")
}
- Manager 클래스에서 invoke가 선언되어 Manager 클래스를 통해 생성한 객체 manager 만으로 접근해 사용할 수 있음
- manager.invoke("...") 형태로 호출되어야 하지만 invoke는 생략하고 객체 이름만 작성
- 코드 읽기가 쉬워짐
- sum = {x: Int, y: Int -> x+y } : 람다식에서는 기본적으로 invoke가 정의됨
- sum.invoke()와 sum()은 같은 동작을 함
인덱스 접근 연산자
인덱스 접근 연산자(Indexed Access Operator) : getter/setter를 다루기 위한 대괄호([]) 연산자를 제공
→ 인덱스 표기법을 통해 값을 읽거나 쓰는 것이 가능
표현식 | 의미 |
a[i] | a.get(i) |
a[i, j] | a.get(i, j) |
a[i_1, ..., i_n] | a.get(i_1, ..., i_n) |
a[i] = b | a.set(i, b) |
a[i, j] = b | a.set(i, j, b) |
a[i_1, ..., i_n] = b | a.set(i_1, ..., i_n, b) |
단일 연산자
먼저 a의 자료형을 결정하고 매개변수 없이 각 연산자에 대한 함수를 호출한 다음 연산된 결과를 반환함
표현식 | 의미 |
+a | a.unaryPlus() |
-a | a.unaryMinus() |
!a | a.not() |
[ 의문점... ]
단일 연산자를 붙인 객체를 바로 출력했을 때는 연산이 된 후의 결과를 반환했지만,
객체에 단일 연산을 한 후에 따로 출력을 했을 때는 연산이 적용되지 않은 것을 확인할 수 있었다.
왜 단일 연산자에서는 연산의 결과가 객체에 저장되지 않는지 잘 모르겠다...
범위 연산자
in 연산자 : 특정 객체를 반복하기 위해 반복문에 사용하거나 범위 연산자와 함께 포함 여부를 판단
표현식 | 의미 |
a in b | b.contains(a) |
a !in b | !b.contains(a) - 범위에 없는 경우 |
대입 연산자
대입 연산자(Augmented Assignment) : 연산의 결과를 할당
a += b 는 a+b를 a에 다시 할당함 && +에 대응하는 plus()를 오버로딩하면 +=는 자동으로 구현됨
- plusAssign()을 따로 오버로딩할 필요가 없음
- 2개를 동시에 오버로딩하면 +의 동작을 무엇으로 할지 모호해지기 때문에 오류 발생
표현식 | 의미 |
a += b | a.plusAssign(b) |
a -= b | a.minusAssign(b) |
a *= b | a.timesAssign(b) |
a /= b | a.divAssign(b) |
a %= b | a.remAssign(b), a.modAssign(b) - 지원 중단 |
동등성 연산자
- 일치와 불일치에 대한 연산자는 두 객체의 값의 동등성을 판별
- ==나 !=는 둘다 equals로 변경되어 동작하는데 인자가 null이어도 동작하도록 되어 있음
- a와 b가 둘다 null이면 true를 반환함
- equals는 Any 안에 operator 키워드가 붙어서 구현되었기 때문에 override 키워드를 사용해서 ==와 치환 가능
- 이런 특이점으로 인해 equals를 확장함수로 구현할 수 없음
- 값과 자료형의 일치를 살펴보는 ===와 !==는 오버로딩 불가능
표현식 | 의미 |
a == b | a?.equals(b) ?: (b === null) |
a != b | !(a?.equals(b) ?: (b === null)) |
: null일 가능성이 있는 a를 세이프 콜로 체크하며, null인 경우에는 null로 표시함.
엘비스 연산자에 의해 a가 null이 아니라면 왼쪽 식, a가 null이면 오른쪽 식을 적용
비교 연산자
표현식 | 의미 |
a > b | a.compareTo(b) > 0 |
a < b | a.compareTo(b) < 0 |
a >= b | a.compareTo(b) >= 0 |
a <= b | a.compareTo(b) <= 0 |
<블로그 내 참고할 포스팅>
언더라인이 있는 글씨를 클릭하면 해당 포스팅으로 넘어가요 :)
드디어 Doit 코틀린 프로그래밍의 절반을 마쳤다!
그동안 공모전도 나가고 해서 독학형 28일차 완성 프로젝트 날짜들을 다 맞추지는 못했지만
남은 반권은 열심히 해서 날짜들을 맞추고 빠르게 한 번 복습하는 시간들도 갖고 싶다! 화이팅!!!
'Kotlin > Kotlin 프로그래밍' 카테고리의 다른 글
[Kotlin] 컬렉션(Collection) - List (0) | 2021.05.24 |
---|---|
[Kotlin] 문자열(String) (0) | 2021.05.21 |
[Kotlin] 배열(Array) (0) | 2021.05.18 |
[Kotlin] 제네릭(Generic) (0) | 2021.05.18 |
[Kotlin] 다양한 클래스와 인터페이스 (2) (0) | 2021.05.10 |
[Kotlin] 다양한 클래스와 인터페이스 (1) (0) | 2021.04.21 |
[Kotlin] 프로퍼티와 초기화 (0) | 2021.04.20 |
[Kotlin] 클래스와 객체 (2) (0) | 2021.04.19 |
댓글