liveBook · Manning

Chapter 9: Operator overloading and other conventions

What you will learn in chapter 9 of Kotlin in Action, 2E

Introduces Kotlin conventions as language operations enabled by specially named functions and explains why extensions make those conventions useful for existing classes.

After this chapter you will be able to

What it builds on

Section by section

Introduction

Introduces Kotlin conventions as language operations enabled by specially named functions and explains why extensions make those conventions useful for existing classes.

Key terms: conventions, plus, operator, extension functions, third-party classes

9.1 Overloading arithmetic operators makes operations for arbitrary classes more convenient

Introduces why Kotlin arithmetic operators are useful for types beyond Java’s usual operands.

Key terms: arithmetic operators, BigInteger, +, +=

9.1.1 Plus, times, divide, and more: Overloading binary arithmetic operations

This section explains how Kotlin maps binary arithmetic syntax to operator functions, including their type flexibility, precedence, and Java interoperability.

Key terms: operator keyword, plus function, extension function, operand types, return type, commutativity, operator functions, binary operators, precedence, infix call syntax

9.1.2 Applying an operation and immediately assigning its value: Overloading compound assignment operators

This section explains how compound assignment can either reassign a computed value or modify an object, and how those choices apply to custom classes and collections.

Key terms: compound assignment operators, plus, plusAssign, operator, Unit, immutable, mutable, mutable collections, read-only collections, var

9.1.3 Operators with only one operand: Overloading unary operators

This section explains how to overload unary operators and how Kotlin preserves the usual prefix and postfix behavior of increment and decrement.

Key terms: unary operator, member, extension, operator, inc, dec, pre-increment, post-increment, BigDecimal

9.2 Overloading comparison operators makes it easy to check relationships between objects

This section introduces Kotlin’s use of comparison operators with objects as a concise alternative to calling comparison methods directly.

Key terms: comparison operators, equals, compareTo

9.2.1 Equality operators: equals (==)

This subsection explains how Kotlin’s equality operators use equals, handle nulls, and differ from identity comparison.

Key terms: ==, !=, equals, nullable operands, identity equals operator, ===, Any, override, operator, extension

9.2.2 Ordering operators: compareTo (<, >, ⇐, and >=)

Explains how Kotlin turns ordering operators into compareTo calls and how a Comparable implementation can define an ordering for a class.

Key terms: Comparable, compareTo, comparison operators, Person, compareValuesBy, selector functions, property references

9.3 Conventions used for collections and ranges

Introduces the operator syntax for indexed access and membership or iteration, and notes that collection-like classes can support these operations.

Key terms: indexed access operator, a[b], in operator, collections, ranges

9.3.1 Accessing elements by index: The get and set conventions

This section explains how Kotlin translates square-bracket reads and assignments into operator functions that classes can define.

Key terms: indexed access operator, get, operator, set, mutable point

9.3.2 Checking whether an object belongs to a collection: The in convention

This section explains how Kotlin’s in operator calls contains and why open ranges suit rectangle membership checks.

Key terms: in operator, contains, open range, closed range, ..< operator

9.3.3 Creating ranges from objects: The rangeTo and rangeUntil conventions

Explains how Kotlin creates ranges with rangeTo and rangeUntil, including ranges of comparable objects and syntax for using range expressions.

Key terms: .., rangeTo, Comparable, range, rangeUntil, ..<, open-end range, upper bound, rangeTo operator, parentheses

9.3.4 Making it possible to loop over your types: The iterator convention

Explains how Kotlin’s iterator convention makes for loops work with built-in and custom types, including date ranges.

Key terms: iterator convention, iterator, hasNext, next, extension function, ClosedRange<LocalDate>, Iterator<LocalDate>

9.4 Making destructuring declarations possible with component functions

This section explains how component functions enable destructuring declarations and how destructuring can unpack returned objects and collections.

Key terms: destructuring declaration, componentN, data class, primary constructor, Pair, Triple, arrays, collections, first five elements

9.4.1 Destructuring declarations and loops

This section shows how destructuring declarations work in loops and lambdas, using map entries as examples.

Key terms: destructuring declarations, iterator, Map.Entry, component1, component2, lambda, composite value, forEach

9.4.2 Ignoring destructured values using the _ character

This section shows how to skip unneeded values in a destructuring declaration and explains why positional destructuring can be fragile.

Key terms: destructuring declaration, component1, component2, _ character, positional, componentN functions, data class, destructuring declarations

9.5 Reusing property accessor logic: Delegated properties

Introduces delegated properties as a way to reuse property accessor logic by handing it to a helper object.

Key terms: delegated properties, delegation, delegate, accessors, backing fields

9.5.1 Basic syntax and inner workings of delegated properties

This section explains how a property delegates its accessor behavior to an object and which functions that object must provide.

Key terms: delegated property, by, delegate, hidden helper property, getValue, setValue, provideDelegate, operator functions, mutable properties

9.5.2 Using delegated properties: Lazy initialization and by lazy()

This section explains why lazy initialization is useful, shows the limitations of implementing it with a backing property, and introduces `by lazy()` as a simpler alternative.

Key terms: lazy initialization, first access, backing property, _emails, emails, thread safe, delegated property, by, lazy, lambda

9.5.3 Implementing your own delegated properties

This section uses observable properties to show how a custom delegate removes repeated setter logic and how Kotlin’s standard library provides an alternative.

Key terms: observable, Observer, ObservableProperty, onChange, by, delegate, operator, getValue, setValue, thisRef

9.5.4 Delegated properties are translated to hidden properties with custom accessors

This section explains how the compiler implements delegated properties and why that mechanism makes property behavior customizable.

Key terms: delegated property, hidden property, KProperty, getValue, setValue, delegated properties, validation, change notifications

9.5.5 Accessing dynamic attributes by delegating to maps

This section shows how a map can back delegated properties for objects with dynamically defined attributes.

Key terms: delegated property, Map, MutableMap, getValue, setValue

9.5.6 How a real-life framework might use delegated properties

This section uses a database framework example to show how delegated properties can make entity attributes behave like ordinary Kotlin properties while controlling how their values are retrieved and updated.

Key terms: Users, User, Entity, columns, delegated property, Column, getValue, setValue, dirty

9.6 Summary

Where this is used later

Concepts explained in this chapter

← Chapter 8: Basic types, collections, and arrays Chapter 10: Higher-order functions:Lambdas as parameters and return values →

These guides are generated from the text of Manning books by Manning's knowledge graph and link to the sections they draw on. The full books are available on liveBook and at manning.com.