A class's primary constructor can be declared right in the class header (class Person(val name: String, var age: Int)), automatically creating and initializing properties from the constructor parameters — eliminating the separate field-declaration-plus-constructor-body boilerplate Java requires. Properties can define custom get()/set() logic when needed. Perhaps most distinctively, every Kotlin class is final by default; a class must be explicitly marked open before it can be subclassed at all, the reverse of Java's open-by-default design, reflecting a deliberate stance that inheritance should be opted into deliberately, not assumed.
The primary constructor: declared in the class header
val/var directly in the constructor parameter list automatically creates a property — no separate field declaration, no manual assignment in a constructor body, unlike Java's usual boilerplate for the same result.
class Person(val name: String, var age: Int) // that's the ENTIRE class — no body needed
val alice = Person("Alice", 30)
println(alice.name) // "Alice" — name and age are real properties, auto-generated
alice.age = 31 // fine — age is a varinit blocks and a custom function
init runs as part of construction, in the order it appears relative to property initializers — useful for validation or setup logic that goes beyond simple property assignment.
class Person(val name: String, var age: Int) {
init {
require(age >= 0) { "Age cannot be negative" } // validation during construction
}
fun greet() = "Hi, I'm $name"
}Classes are final by default — the opposite of Java
Attempting to extend Person without open on the class is a compile error — Kotlin requires this to be an explicit, deliberate choice by the class's original author, not an accident of forgetting to mark something final.
class Person(val name: String) // final by default
// class Employee : Person("x") // COMPILE ERROR: Person is final, can't be inherited
open class Animal(val name: String) // explicitly open — CAN be extended
class Dog(name: String) : Animal(name) // fine — Animal was marked open