What you'll learn
Classes are the foundation of object-oriented Kotlin — and Kotlin makes them remarkably concise. This module covers declaring classes, its clever primary constructor, init blocks, and secondary constructors.
By the end you'll be able to:
- Declare classes and create instances (no
new!) - Use the primary constructor to declare properties in the header
- Run setup code in
initblocks - Add secondary constructors when you need them
Declaring classes & creating objects
You declare a class with class, and you create an object by calling it like a function — Kotlin has no new keyword. Notice how little code this takes:
// the primary constructor declares properties right in the header
class Person(val name: String, var age: Int)
val p = Person("Sara", 25) // no 'new' keyword in Kotlin
println(p.name) // Sara
p.age = 26 // var can change
println(p.age) // 26The primary constructor
The magic is the primary constructor — declared right in the class header. By adding val or var to a parameter, you declare a property and a constructor parameter at the same time. What takes a dozen lines in Java is one line in Kotlin:
class Person(val name: String, var age: Int)val / var in the header
Declares a property and a constructor parameter in one go.
No body needed
This entire class is just one line — no boilerplate.
Key idea
class Person(val name: String, var age: Int) declares the class, its constructor, two properties, and their assignment — all in one line. This conciseness is a huge part of Kotlin's appeal.init blocks
The primary constructor can't contain code, so for setup logic — validation, logging, computing derived values — you use an init block. It runs when the object is created, and can see the constructor parameters:
class Account(val owner: String, initial: Double) {
var balance = initial
init { // runs during construction
println("Account created for $owner")
}
}
val acc = Account("Sara", 100.0)
acc.balance += 50
println(acc.balance)Tip
init, use require(condition) { "message" } — it throws a clear IllegalArgumentException if the condition is false. It's the idiomatic way to reject bad constructor arguments.Secondary constructors
Sometimes you want an alternative way to build an object. A secondary constructor (with the constructor keyword) must delegate to the primary one using this(...):
class Rectangle(val width: Int, val height: Int) {
// a secondary constructor must delegate to the primary via this(...)
constructor(size: Int) : this(size, size)
val area get() = width * height
}
println(Rectangle(3, 4).area) // 12
println(Rectangle(5).area) // 25 (a square)Note
Recap & quick check
Key takeaways
- Create objects by calling the class like a function — Kotlin has no 'new' keyword.
- The primary constructor is in the class header; val/var there declares a property and parameter at once.
- init blocks hold construction-time setup and validation (use require for argument checks).
- Secondary constructors use the 'constructor' keyword and must delegate to the primary via this(...).
- Prefer a primary constructor with default arguments over multiple secondary constructors.
Quick check
1. How do you create an object in Kotlin?
2. What does adding 'val' to a primary-constructor parameter do?
3. Where does construction-time setup code go?
4. What must a secondary constructor do?
5. What usually replaces secondary constructors in Kotlin?
Great — you can define your own types now. Next up: Module 14 — Properties, Getters & Backing Fields.