Chapter 6 of 12
~20 min read
Classes & Objects
Kotlin classes are more concise than Java — no boilerplate getters/setters, no-braces constructors, and smarter defaults.
Class Declaration
Java
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
} Kotlin
class Person(
val name: String, // immutable property
var age: Int // mutable property
)
// That's it! Constructor + properties in one line.
// Usage:
val p = Person("Alice", 30)
println(p.name) // Alice
p.age = 31 // direct access — no setters! Properties, not fields
Kotlin automatically generates getters for val and getters+setters for var. When calling from Java, these appear as getName() and setAge(). From Kotlin, you use direct dot access: p.name.
init Block
Kotlin
class Person(val name: String, var age: Int) {
val displayName: String
init {
// Runs on construction — like Java constructor body
displayName = name.trim().uppercase()
require(age >= 0) { "Age must be non-negative" }
}
}Inheritance — open Required
In Java, all classes are open for inheritance by default. In Kotlin, classes and methods are final by default — you must explicitly mark them open:
Java
// Open by default!
public class Animal {
public String speak() {
return "...";
}
}
public class Dog extends Animal {
@Override
public String speak() {
return "Woof!";
}
} Kotlin
// Final by default!
open class Animal {
open fun speak() = "..."
}
class Dog : Animal() {
override fun speak() = "Woof!"
}
// Non-open class can't be extended:
class Cat // final — cannot extendcompanion object vs Java static
Kotlin has no static keyword. Use companion object for class-level members:
Java
public class ApiClient {
private static final String BASE_URL =
"https://api.example.com";
private static ApiClient instance;
public static ApiClient getInstance() {
if (instance == null)
instance = new ApiClient();
return instance;
}
public static String getBaseUrl() {
return BASE_URL;
}
} Kotlin
class ApiClient {
companion object {
const val BASE_URL = "https://api.example.com"
// Can implement factory pattern:
fun create() = ApiClient()
}
}
// Call like Java static:
ApiClient.BASE_URL
ApiClient.create()object — Singleton in One Keyword
Java — singleton boilerplate
public class Logger {
private static Logger instance;
private Logger() {}
public static Logger getInstance() {
if (instance == null)
instance = new Logger();
return instance;
}
public void log(String msg) {
System.out.println("[LOG] " + msg);
}
} Kotlin — one keyword
object Logger {
fun log(msg: String) {
println("[LOG] $msg")
}
}
// Usage — no getInstance() needed:
Logger.log("App started")