In Kotlin Multiplatform, what does declaring `expect class Platform` in common code and `actual class Platform` in a platform source set mean? Give a minimal example.
answer
- expect = signatures only, no body
- actual = one implementation per target
- compile-time binding, no runtime interface
- every member needs actual, including constructor
- lives in commonMain vs platform source sets
basics
~20 sYou write a placeholder class in shared code that says 'this exists, here's its shape.' Each platform (Android, iOS) then provides the real version with the same name and members. Shared code uses it without knowing the platform.
solid answer
~40 s`expect class Platform` is a declaration in the `commonMain` source set with no body for its members — it states the contract (constructors, methods, properties) that every target must satisfy. Each platform source set (e.g. `androidMain`, `iosMain`) supplies an `actual class Platform` with a matching signature, implemented using platform-specific APIs (java.lang on JVM, Foundation on iOS). The compiler links each `expect` to exactly one `actual` per target at compile time — there is no runtime indirection or interface. Common code calls `Platform()` and gets the right implementation depending on which target you compile. The `actual` must match the `expect` exactly: same name, package, type parameters, and member signatures. This is the core mechanism letting one shared API surface have N platform-specific bodies.
code
kotlin · 12 lines// commonMain
expect class Platform() {
val name: String
}
// jvmMain
actual class Platform actual constructor() {
actual val name: String = System.getProperty("os.name")
}
// commonMain usage
fun describe() = "Running on ${Platform().name}"go deeper
Can state expect is the shared signature and actual is the per-platform implementation, and write a trivial matching pair.
Explains compile-time binding, the one-actual-per-target rule, and that common code only sees expect members.
Contrasts with interfaces/DI, notes expect object, and discusses where actuals live across source sets and the constructor actualization.
Frames it as a build-graph contract, weighs expect/actual vs typealias-to-platform-type or interface+factory for API stability and binary compatibility.
## What expect/actual solves Kotlin Multiplatform (KMP) lets you share code across targets (JVM/Android, iOS/native, JS, Wasm). Most code is shared, but some needs a **platform-specific implementation** (e.g. reading the OS name, a UUID, a crypto primitive). The `expect`/`actual` mechanism is Kotlin's way to declare an API in shared code and bind a real implementation per target. ## expect = the contract In `commonMain` you write: ```kotlin // commonMain expect class Platform() { val name: String fun greet(): String } ``` An **expected** declaration has no implementation — only signatures. It is the *promise* that an actual exists for every target. ## actual = the implementation Each platform source set provides the body: ```kotlin // androidMain actual class Platform actual constructor() { actual val name: String = "Android " + android.os.Build.VERSION.SDK_INT actual fun greet(): String = "Hi from $name" } // iosMain actual class Platform actual constructor() { actual val name: String = platform.UIKit.UIDevice.currentDevice.systemName() actual fun greet(): String = "Hi from $name" } ``` Every member that was expected must be marked `actual`, including the constructor (`actual constructor()`). ## Key facts - **Compile-time binding**: the compiler matches each `expect` to one `actual` per target. No reflection, no runtime dispatch, no generated interface. - **One actual per target**: missing an actual for any compiled target is a compile error. - **Common code is target-agnostic**: it just calls `Platform().greet()`. - **expect object** works too: `expect object Config` matched by `actual object Config`. - Members can also be **optionally** actualized by inheritance or by `actual typealias` (a sibling topic), but the direct form is a matching `actual class`. ## Why not just an interface? An interface needs a runtime implementation chosen by you; expect/actual is resolved by the build target, so shared code references a concrete type (`Platform`) with zero ceremony and full inlining/value-class friendliness.
- What happens if you forget to provide an actual for one of the compiled targets?It is a compile-time error for that target's compilation — the build fails until every expected declaration has a matching actual.
- Can common code see the platform-specific fields of the actual class?No. Common code only sees what the expect declares. Extra members added to an actual are invisible from commonMain.
expect is a job description posted to shared code; each platform hires its own employee (actual) that must match the description exactly.
saying these in an interview costs you the question
- Thinking expect/actual is resolved at runtime via reflection or DI
- Believing the actual can have a different name or package than the expect
- Saying expect classes need a body in commonMain
- Confusing it with regular interface/abstract-class polymorphism
- Forgetting the constructor itself needs to be actualized