1. 산술 연산자 오버로딩
자바 : 원시타입, String 만 가능하다.
코틀린 : 클래스, 컬렉션에도 적용 가능
1-1. 이항 산술 연산 오버로딩 + - * / %
클래스 내부에 operator fun plus 를 추가한다
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) // Point(40, 60)
// 실제로, p1.plus(p2) 로 호출된다.
}
식 함수이름
특징
- 연산자 우선순위와 같게 진행된다
- *, /, % 우선순위가 같고 +, -가 같다
- 두 피연산자가 같은 타입일 필요 없다.
1-2. 복합 대입 연산자 += -=
연산자 오버로딩(+, -…)을 하면 연산자 뿐 아니라 관련있는 +=, -= 등도 자동으로 지원한다.
fun main() {
var p1 = Point(10, 20)
var p2 = Point(30, 40)
p1 += p2
println(p1) // Point(40, 60)
}
컬렉션에서의 사용
fun main() {
val numbers = mutableListOf<Int>()
numbers += 1
numbers += 2
numbers += 3
numbers -= 2
println(numbers) // [1, 3]
}
- 없을때 빼도 오류가 나지 않는다!
1-3. 단항 연산자 오버로딩
이항 연산 : a + b
단항 연산 : -a
operator fun Point.unaryMinus(): Point {
return Point(-x, -y)
}
fun main() {
val p = Point(10, 20)
print(-p) // Point(-10, -20)
}
오버로딩할 수 있는 단항 산술 연산자
식 함수이름
+a | unaryPlus |
-a | unaryMinus |
!a | not |
++a, a++ | inc |
—a, a— | dec |
2. 비교 연산자 오버로딩
2-1. 동등성 연산자 ==
코틀린의 ==, != 연산자는 equals 메서드 호출로 컴파일한다.
- 사용은 ==
- 오버리이딩은 equals
class Point(val x:Int, val y:Int) {
override fun equals(obj: Any?): Boolean {
if (obj === this) return true
if (obj !is Point) return false
return obj.x == x && obj.y == y
}
}
식별자비교(===) : 자바의 ==과 같다. 식별자비교는 오버로딩 할 수 없다.
2-2. 순서 연산자 >=
자바에서 정렬, 최대값, 최소값을 비교할 때 Comparable 인터페이스를 구현해야 한다. 코틀린도 마찬가지
- 사용 : >=
- 오버라이딩 : compareTo
class Person(val firstName: String, val lastName: String) : Comparable<Person>{
override fun compareTo(other: Person): Int {
return compareValuesBy(this, other, Person::lastName, Person::firstName)
}
}
3. 컬렉션과 범위에 대해 쓸 수 있는 관례
3-1. 인덱스로 원소에 접근 [] ⇒ get set
- 사용 : val value = map[key]
- 사용시 get 연산자 메서드로 변환되고 쓰는 연산은 set 연산자 메서드로 변환된다.
3-2. in 관례 contains
in 연산자와 대응하는 함수는 contains다.
3-3. .. 관례 rangeTo
1..10 구문 : 1부터 10까지 모든 수가 들어있는 범위를 가리킨다.
start..end → start.rangeTo(end)
3-4. for 루프를 위한 iterator 관례
iterator : 자바의 컬렉션 프레임워크에서 컬렉션에 저장되어 있는 요소들을 읽어오는 방법을 표준화한 것
코틀린에서도 iterator 메서드를 확장함수로 정의할 수 있다.
4. 구조 분해 선언과 component 함수
구조 분해 선언
val (a, b) = p
// val a = p.component1()
// val b = p.component2()
- component1 확장함수가 제공됨 (코틀린 라이브러리)
5. 프로퍼티 접근자 로직 재활용: 위임 프로퍼티
프로퍼티는 위임을 사용해 자신의 값을 필드가 아닌 DB나 브라우저 세션, 맵 등에 저장할 수 있다.
위임 : 객체가 직접 작업을 수행하지 않고 다른 도우미 객체가 그 작업을 처리하게 맡기는 디자인 패턴
1. 프로퍼티 초기화 지연 by lazy()
지연 : 실제고 그 부분의 값이 필요한 경우 초기화할 때 쓰임
class Person(val name: String) {
val emails by lazy { loadEmails(this) }
}
2. 위임 프로퍼티 구현
open class PropertyChangeAware {
protected val changeSupport = PropertyChangeSupport(this)
fun addPropertyChangeListener(listener: PropertyChangeListener) {
changeSupport.addPropertyChangeListener(listener)
}
fun removePropertyChangeListener(listener: PropertyChangeListener) {
changeSupport.removePropertyChangeListener(listener)
}
}
class ObservableProperty(var propValue: Int, val changeSupport: PropertyChangeSupport) {
operator fun getValue(p: Person, prop: KProperty<*>): Int = propValue
operator fun setValue(p: Person, prop: KProperty<*>, newValue: Int) {
val oldValue = propValue
propValue = newValue
changeSupport.firePropertyChange(prop.name, oldValue, newValue)
}
}
class Person (val name:String, age:Int, salary: Int) : PropertyChangeAware() {
var age: Int by ObservableProperty(age, changeSupport)
var salary: Int by ObservableProperty(salary, changeSupport)
}
kotlin in action 책을 통한 공부입니다.
'공부 > Kotlin' 카테고리의 다른 글
9장 제네릭스 (0) | 2022.07.02 |
---|---|
[Kotlin] 파라미터와 반환 값으로 람다 사용해보기 (0) | 2022.07.02 |
[Kotlin] 코틀린 타입 시스템 사용해보기 (0) | 2022.06.20 |
4장. 클래스, 객체, 인터페이스 (0) | 2022.06.07 |
3장. 함수 정의와 호출 (0) | 2022.06.07 |
댓글