skip to content

How do properties work in Kotlin interfaces? Explain abstract properties (no backing field) and properties with default accessors.

level: middleimportance: must knowfreq 60%

answer

  1. Interfaces have no backing field
  2. Abstract property → class must supply it
  3. Custom `get() = ...` is allowed (computed, no storage)
  4. `val x = 5` and `field` are illegal in interfaces
  5. `var` declares get/set contract; class backs it

basics

~10 s

An 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 s

Interfaces 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 lines
kotlin
interface 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.0

go deeper

for a junior

Knows interfaces can declare properties that the class must implement.

for a middle

Explains 'no backing field', distinguishes abstract property from property-with-default-getter, and knows = value/field are illegal.

for a senior

Maps interface property forms to the abstract/default method duality and shows constructor-property satisfaction patterns.

for a principal

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

context