56. Purpose of the by Keyword in Kotlin
In Kotlin, the by keyword is used for delegation — allowing one object or property to delegate its implementation or behavior to another.
There are two main usages:
1. 🧱 Class Delegation
Allows a class to delegate interface implementation to another object.
interface Logger {
fun log(message: String)
}
class ConsoleLogger : Logger {
override fun log(message: String) {
println("LOG: $message")
}
}
class AppLogger(private val logger: Logger) : Logger by logger
AppLogger implements Logger, but delegates the actual log() call to the ConsoleLogger instance — no need to write boilerplate.
Lets a property delegate its getter/setter logic to another object (like lazy, observable, etc.).
val config: String by lazy {
println("Initializing config...")
"ProductionConfig"
}
Example 2: observable
import kotlin.properties.Delegates
var name: String by Delegates.observable("Unknown") { _, old, new ->
println("Name changed from $old to $new")
}
57. The concept of operator overloading in Kotlin
Operator overloading in Kotlin allows you to define custom behavior for standard operators (like +, -, *, ==, [], etc.) on your own types (classes).
Kotlin lets you "overload" predefined operators by defining functions with special names, prefixed with the operator keyword.
Example: Overloading the + Operator
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(1, 2)
val p2 = Point(3, 4)
val result = p1 + p2 // same as p1.plus(p2)
println(result) // Output: Point(x=4, y=6)
}
Common Overloadable Operators in Kotlin
Operator | Function Name | Example Usage |
---|---|---|
+ | plus | a + b |
- | minus | a - b |
* | times | a * b |
/ | div | a / b |
% | rem | a % b |
[] | get / set | a[i] |
== | equals | a == b |
> < | compareTo | a > b, a < b |
++ | inc | a++ |
-- | dec | a-- |
! | not | !a |
in | contains | x in a |
.. | rangeTo | a..b |
Example: Overloading get and set (like array access)
class Matrix {
private val data = Array(3) { IntArray(3) }
operator fun get(i: Int, j: Int): Int = data[i][j]
operator fun set(i: Int, j: Int, value: Int) {
data[i][j] = value
}
}
val m = Matrix()
m[0, 1] = 42
println(m[0, 1]) // Output: 42
58. The purpose of the when expression in Kotlin?
The when expression in Kotlin is a powerful replacement for the switch statement (in Java or C-like languages). It allows you to match a value against multiple conditions and execute different code for each case.
Basic Syntax
val result = when (value) {
1 -> "One"
2 -> "Two"
else -> "Other"
}
It can be used as:
Examples
1. Simple match
val x = 2
val text = when (x) {
1 -> "One"
2 -> "Two"
3 -> "Three"
else -> "Unknown"
}
2. Multiple conditions in one branch
when (x) {
0, 1 -> println("x is 0 or 1")
in 2..10 -> println("x is between 2 and 10")
else -> println("x is something else")
}
3. When without argument
when {
x % 2 == 0 -> println("Even")
x % 2 != 0 -> println("Odd")
}
4. Type checking with is
fun printType(obj: Any) {
when (obj) {
is String -> println("It's a String")
is Int -> println("It's an Int")
else -> println("Unknown type")
}
}
*Importants:
Feature | Description |
---|---|
Flexible match | Matches values, ranges, conditions, types |
Expression | Can return a value |
Pattern match | Can be used without a subject (when {}) |
Type-safe | Works with all Kotlin types |
59. Explain primary constructor in Kotlin.
A primary constructor is a concise way to initialize a class and its properties in Kotlin. It is defined in the class header, directly after the class name.
Syntax
class Person(val name: String, var age: Int)
This automatically:
Example with Primary Constructor
class User(val username: String, val email: String)
fun main() {
val user = User("john_doe", "john@example.com")
println(user.username) // Output: john_doe
}
Primary Constructor with Init Block
class Product(val name: String, val price: Double) {
init {
println("Product created: $name costs $price")
}
}
*Importants
Concept | Description |
---|---|
Primary Constructor | Defined in class header |
Properties | Declared and initialized from constructor parameters |
init block | Used for additional initialization logic |
Recommended | Over secondary constructors for clarity and simplicity |
60. Primary Constructor vs Secondary Constructor
Feature | Primary Constructor | Secondary Constructor |
---|---|---|
Definition Location | Declared in the class header | Declared inside the class body |
Purpose | Used for initializing main properties | Used for additional ways to instantiate the class |
Initialization block (init) | Commonly used with init block | Must delegate to the primary constructor |
Parameter Declaration | Parameters declared directly in class definition | Declared in the constructor itself |
Default Use Case | Default and most common constructor | Used when alternative construction logic is needed |
Number of Constructors | Only one per class | Multiple can be defined |
Property Declaration | Can declare and initialize properties inline | Cannot directly declare properties |
Delegation | No need to delegate | Must delegate to primary constructor using this() |