How do properties work in Kotlin interfaces? Explain abstract properties (no backing field) and properties with default accessors.
answer
- Interfaces have no backing field
- Abstract property → class must supply it
- Custom `get() = ...` is allowed (computed, no storage)
- `val x = 5` and `field` are illegal in interfaces
- `var` declares get/set contract; class backs it
basics
~10 sAn interface property has no stored value—no backing field. It can be abstract (the class must provide it) or it can define a getter that computes a value from other members.
solid answer
~40 sInterfaces can declare properties but never store them: there is no backing field. A property like `val name: String` is abstract—the implementing class must supply it, typically as a stored `override val name`. A property can instead define a **custom accessor** in the interface: `val label: String get() = "User: $name"`. That getter is a default implementation computed each access from other members; it works because it doesn't need storage. You cannot write `val x: Int = 5` in an interface (that would need a backing field), nor can you use `field` inside an interface accessor. `var` properties in interfaces declare `get`/`set` contracts; a concrete class provides the backing. This is the property analogue of abstract vs default methods.
code
kotlin · 10 linesinterface HasArea {
val width: Double // abstract
val height: Double // abstract
val area: Double // default accessor — no backing field
get() = width * height
}
class Rect(override val width: Double, override val height: Double) : HasArea
fun main() = println(Rect(2.0, 3.0).area) // 6.0go deeper
Knows interfaces can declare properties that the class must implement.
Explains 'no backing field', distinguishes abstract property from property-with-default-getter, and knows = value/field are illegal.
Maps interface property forms to the abstract/default method duality and shows constructor-property satisfaction patterns.
Reasons about contract design: when to expose computed defaults vs abstract properties for stable, evolvable interface APIs.
## The core constraint: no backing field A *backing field* is the hidden storage slot the compiler generates for a normal property. **Interfaces have no backing fields**, because they have no instance state and no constructor. Everything about interface properties follows from that. ## Two legal forms ```kotlin interface User { val id: String // 1) abstract property — class must supply it val displayName: String // abstract too get() = "User#$id" // 2) property with a default getter (no storage) } ``` - **Abstract property** (`val id: String` with no accessor): there is no value and no getter body. The implementing class must provide one, usually by storing it: `override val id = "..."` or a constructor `val`. - **Property with a custom accessor** (`val displayName ... get() = ...`): the getter is a *default implementation* computed from other members each time it's read. Because it computes rather than stores, no backing field is needed, so it's allowed. ## What is NOT allowed - `val x: Int = 5` in an interface — an initializer needs a backing field. **Illegal.** - Using `field` inside an interface accessor — there is no field to reference. **Illegal.** - Lazy/delegated storage that requires per-instance state directly on the interface in a way that needs a field. ## var properties A `var` in an interface declares both a `get` and `set` contract. You may give the getter a default body, but a settable property generally needs the class to provide storage: ```kotlin interface Counter { var count: Int // class must back this fun bump() { count += 1 } // default method using the property } class MemCounter : Counter { override var count: Int = 0 // backing field lives here, in the class } ``` ## How implementers satisfy them The usual way to satisfy an abstract interface property is a constructor property or a stored `override`: ```kotlin class DbUser(override val id: String) : User // displayName inherited via default getter ``` ## Mental model Interface property = a **contract about a getter (and maybe setter)**, optionally with a computed default, never a stored value. This mirrors abstract vs default *methods*: abstract property ↔ abstract method, property-with-accessor ↔ default method.
- Why can't you write `val x: Int = 0` in an interface?An initializer requires a backing field to hold the value, and interfaces have no backing fields, so the compiler rejects it.
- Can an interface declare a `var` with a default getter?Yes for the getter, but a settable property normally still needs the implementing class to provide storage for the setter to write to.
An interface property is a label on an empty shelf: it names what should be there, but the implementing class actually stocks it.
saying these in an interview costs you the question
- Claiming interface properties have backing fields
- Saying you can initialize an interface property with `= value`
- Trying to use `field` in an interface accessor
- Confusing a computed `get()` property with stored state