Classes
## Learning Objectives
- Understand class declarations and constructors
- Work with properties
- Create data classes
- Use object expressions and companion objects
- Learn about copy functionality
## Class Declaration
### Basic Class
```kotlin
class Person {
var name: String = ""
var age: Int = 0
fun introduce() {
println("Hi, I'm $name, age $age")
}
}
fun main() {
val person = Person()
person.name = "Alice"
person.age = 30
person.introduce()
}
```
## Constructors
### Primary Constructor
```kotlin
class Person(val name: String, var age: Int) {
fun introduce() {
println("Hi, I'm $name, age $age")
}
}
fun main() {
val person = Person("Alice", 30)
person.introduce()
}
```
### Constructor Properties
The primary constructor can declare properties directly:
```kotlin
class Person(val name: String, var age: Int)
```
This is equivalent to:
```kotlin
class Person(name: String, age: Int) {
val name: String = name
var age: Int = age
}
```
### Default Values in Constructor
```kotlin
class Person(val name: String, var age: Int = 18) {
fun introduce() {
println("Hi, I'm $name, age $age")
}
}
fun main() {
val person1 = Person("Alice")
person1.introduce() // Hi, I'm Alice, age 18
val person2 = Person("Bob", 25)
person2.introduce() // Hi, I'm Bob, age 25
}
```
### Secondary Constructors
```kotlin
class Person {
val name: String
var age: Int
constructor(name: String) {
this.name = name
this.age = 0
}
constructor(name: String, age: Int) {
this.name = name
this.age = age
}
fun introduce() {
println("Hi, I'm $name, age $age")
}
}
fun main() {
val baby = Person("Charlie")
baby.introduce() // Hi, I'm Charlie, age 0
val adult = Person("Diana", 35)
adult.introduce() // Hi, I'm Diana, age 35
}
```
### Init Blocks
```kotlin
class Person(name: String, var age: Int) {
val name: String
init {
this.name = name.uppercase()
require(age >= 0) { "Age cannot be negative" }
}
fun introduce() {
println("Hi, I'm $name, age $age")
}
}
fun main() {
val person = Person("alice", 30)
person.introduce() // Hi, I'm ALICE, age 30
}
```
## Properties
### Read-only Properties (val)
```kotlin
class Person(val name: String, val birthYear: Int) {
val age: Int
get() = 2024 - birthYear
fun introduce() {
println("$name is $age years old")
}
}
fun main() {
val person = Person("Alice", 1990)
person.introduce() // Alice is 34 years old
}
```
### Custom Getters and Setters
```kotlin
class Person {
var name: String = ""
set(value) {
field = value.trim()
}
get() = field.ifEmpty { "Unknown" }
var age: Int = 0
set(value) {
if (value >= 0) {
field = value
}
}
}
fun main() {
val person = Person()
println(person.name) // Unknown
person.name = " Alice "
println(person.name) // Alice
person.age = -5 // Ignored
println(person.age) // 0
}
```
### Late Initialization
```kotlin
class Person {
lateinit var name: String
fun initialize() {
name = "Alice"
}
fun introduce() {
if (::name.isInitialized) {
println("Hi, I'm $name")
}
}
}
fun main() {
val person = Person()
person.introduce() // Nothing printed
person.initialize()
person.introduce() // Hi, I'm Alice
}
```
## Data Classes
Data classes automatically generate:
- `equals()` / `hashCode()`
- `toString()`
- `componentN()` functions
- `copy()`
```kotlin
data class User(val name: String, val email: String, val age: Int)
fun main() {
val user1 = User("Alice", "alice@example.com", 30)
val user2 = User("Alice", "alice@example.com", 30)
println(user1) // User(name=Alice, email=alice@example.com, age=30)
// Automatic equality check
println(user1 == user2) // true
println(user1.hashCode() == user2.hashCode()) // true
// Destructuring
val (name, email, age) = user1
println("$name, $email, $age")
}
```
### Copy Function
```kotlin
data class User(val name: String, val email: String, val age: Int)
fun main() {
val alice = User("Alice", "alice@example.com", 30)
// Copy with modified fields
val olderAlice = alice.copy(age = 31)
println(alice) // User(name=Alice, email=alice@example.com, age=30)
println(olderAlice) // User(name=Alice, email=alice@example.com, age=31)
// Copy with different email
val newEmailAlice = alice.copy(email = "newalice@example.com")
println(newEmailAlice)
}
```
## Object Expressions
### Anonymous Objects
```kotlin
fun main() {
val person = object {
val name: String = "Anonymous"
val age: Int = 25
fun introduce() {
println("Hi, I'm $name")
}
}
person.introduce()
}
```
### Object Expressions with Interfaces
```kotlin
interface Greeter {
fun greet(): String
}
fun main() {
val greeter = object : Greeter {
override fun greet() = "Hello!"
}
println(greeter.greet())
}
```
## Companion Objects
A companion object provides functionality similar to static methods in Java:
```kotlin
class Person(val name: String) {
companion object {
private var count = 0
fun createAnonymous(): Person {
count++
return Person("Person #$count")
}
const val SPECIES = "Human"
}
}
fun main() {
val p1 = Person.createAnonymous()
val p2 = Person.createAnonymous()
println(p1.name) // Person #1
println(p2.name) // Person #2
println(Person.SPECIES) // Human
}
```
### Companion Object as Named Object
```kotlin
class MyClass {
companion object Factory {
fun create(): MyClass = MyClass()
}
}
fun main() {
val obj = MyClass.Factory.create()
// or simply
val obj2 = MyClass.create()
}
```
## Sealed Classes
```kotlin
sealed class Result {
data class Success(val data: T) : Result()
data class Error(val message: String) : Result()
object Loading : Result()
}
fun main() {
val result: Result = Result.Success("Hello")
when (result) {
is Result.Success -> println("Success: ${result.data}")
is Result.Error -> println("Error: ${result.message}")
is Result.Loading -> println("Loading...")
}
}
```
## Enum Classes
```kotlin
enum class Color(val rgb: Int) {
RED(0xFF0000),
GREEN(0x00FF00),
BLUE(0x0000FF);
fun hex() = "#${Integer.toHexString(rgb)}"
}
fun main() {
val color = Color.BLUE
println(color) // BLUE
println(color.hex()) // #ff0000
// Iterate over enum values
for (c in Color.entries) {
println("${c.name}: ${c.hex()}")
}
}
```
## Summary
- Classes declared with `class` keyword
- Primary constructor defined in class header
- Properties use `val` (read-only) or `var` (mutable)
- `data class` auto-generates equals, hashCode, toString, copy
- Object expressions create anonymous objects
- Companion object provides static-like members
- Sealed classes restrict inheritance for exhaustive when
- Enum classes represent fixed set of values
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →