skip to content

Classes & Objects

Kotlin's object model end to end: constructors and properties, data, sealed and value classes, enums, objects and companions, inheritance rules, and built-in delegation. This is the largest everyday surface of the language and interviews reflect that.

part ofKotlinoverview, primer and where to startread it →
on this pageshow

explore

questions

173 · 9 sections

In Kotlin, what are the default visibility and inheritance modifiers for a top-level class declared with just `class Foo`, and why were those defaults chosen?

level: juniorimportance: must knowfreq 78%
basics
~10 s

A plain Kotlin class is public so any code can use it, and final so nobody can subclass it. To allow subclassing you must write the keyword open.

open as a page

Kotlin makes singletons a first-class language feature with `object`. Describe object declarations, companion objects, and object expressions, and how each is initialized.

level: middleimportance: must knowfreq 72%
basics
~20 s

object Foo { } declares a single, lazily created instance — a built-in singleton. A companion object is the one singleton attached to a class for 'static-like' members. An object : Type { } expression creates a one-off anonymous object on the spot.

open as a page

Explain how Kotlin's primary constructor can declare properties inline, and what `val`/`var` in the constructor header does versus a plain parameter. When do you need an `init` block or a secondary constructor?

level: middleimportance: must knowfreq 80%
basics
~10 s

Putting val or var before a primary-constructor parameter makes it a stored property of the class in one line. Without val/var it's just a constructor argument. init blocks run setup code at construction.

open as a page

Kotlin makes delegation a language feature via the `by` keyword for both interfaces and properties. Explain class/interface delegation and property delegation, and what the compiler generates.

level: seniorimportance: should knowfreq 58%
basics
~20 s

by lets one object hand off work to another automatically. For interfaces, a class can implement an interface by forwarding all its methods to a held object. For properties, getting/setting a value can be routed through a helper like lazy or Delegates.observable.

open as a page

Kotlin maps OOP onto the JVM with opinionated defaults (final classes, no statics, language-level delegation). As an API designer, what are the consequences of these choices for library evolution, Java interop, and framework integration?

level: principalimportance: nice to knowfreq 32%
basics
~20 s

Kotlin's defaults make code safer and shorter but require extra care: final classes can block frameworks that subclass your types, and 'no statics' plus companions need annotations for clean Java use. Plan these at the API boundary.

open as a page

What is a computed property in Kotlin, and how do you write one using a custom get()?

level: juniorimportance: must knowfreq 70%
basics
~10 s

A computed property has no stored value. Each time you read it, a custom get() runs and calculates the result on the fly from other data, instead of returning something saved in memory.

open as a page

What is an `init {}` block in Kotlin, and when does its code run relative to the primary constructor?

level: juniorimportance: must knowfreq 70%
basics
~20 s

An init {} block holds setup code that runs when you create an object. It runs as part of the primary constructor, after the constructor parameters are available but as the object is being built.

open as a page

In Kotlin, what is the difference between a class declared inside another class with no modifier versus one declared with the `inner` keyword?

level: juniorimportance: must knowfreq 70%
basics
~20 s

By default a class inside another class is nested and standalone: it does not know about the outer object. Adding the inner keyword links it to an outer instance, so it can use the outer object's data.

open as a page

What is a Kotlin primary constructor, and how can it declare class properties directly in the class header?

level: juniorimportance: must knowfreq 80%
basics
~10 s

The primary constructor is written in the class header. If you put val or var before a parameter, Kotlin creates a property with that name automatically, so you don't write extra assignment code.

open as a page

What is the difference between a `val` and a `var` property in Kotlin, and what does the compiler generate for each?

level: juniorimportance: must knowfreq 85%
basics
~10 s

A val is read-only — you set it once and can't reassign it. A var can be reassigned. The compiler creates a getter for both, and a setter only for var.

open as a page

What is a destructuring declaration in Kotlin, and what makes `val (a, b) = point` work under the hood?

level: juniorimportance: must knowfreq 70%
basics
~10 s

It lets you pull several values out of one object in a single line, like val (x, y) = point. Kotlin does it by calling special functions named component1(), component2(), and so on.

open as a page

What does the generated copy() function on a Kotlin data class do, and why is it useful for immutable data?

level: juniorimportance: must knowfreq 80%
basics
~10 s

copy() makes a new object that is the same as the old one, except for the properties you choose to change. The original stays untouched, so you update data without modifying it in place.

open as a page

What members does the Kotlin compiler auto-generate when you mark a class as a `data class`, and what drives their content?

level: juniorimportance: must knowfreq 85%
basics
~10 s

Marking a class data makes the compiler write equals(), hashCode(), and toString() for you, based on the properties declared in the primary constructor, so you don't write that boilerplate by hand.

open as a page

What are the requirements on a data class's primary constructor, and why won't `data class Empty()` compile?

level: juniorimportance: must knowfreq 70%
basics
~20 s

A data class must declare a primary constructor with at least one parameter, and every parameter must be marked val or var. An empty parameter list, or a plain parameter without val/var, is a compile error.

open as a page

Exactly which properties of a data class get a generated componentN(), and what gotchas does that create for destructuring?

level: middleimportance: must knowfreq 50%
basics
~10 s

Only the properties listed in the data class's main constructor get componentN() functions, in the order they're written. Properties declared inside the class body don't get one, so you can't destructure them.

open as a page

What is a sealed class (or sealed interface) in Kotlin, and what does the sealed modifier guarantee about its subtypes?

level: juniorimportance: must knowfreq 80%
basics
~20 s

A sealed class or interface is one where the compiler knows the complete, fixed list of all its direct subtypes. New subtypes can't be added from outside, so the set of possibilities is closed and known at compile time.

open as a page

When you use `when` as an expression over a sealed type and cover every subtype, why don't you need an `else` branch?

level: juniorimportance: must knowfreq 70%
basics
~10 s

Because the sealed type lists all its possible subtypes in advance. If you handle each one, the compiler knows nothing else is possible, so an else branch would be pointless.

open as a page

You need to represent a screen that can be loading, show data, or show an error. How would you model this with a sealed type, and why is that better than three nullable fields?

level: juniorimportance: must knowfreq 80%
basics
~10 s

Make a sealed type with three cases: Loading, Success holding the data, and Error holding a message. Only one case can exist at a time, so you can never have a half-loaded, half-errored screen.

open as a page

What is the core difference between a Kotlin enum class and a sealed class/interface, and when would you reach for each?

level: juniorimportance: must knowfreq 80%
basics
~20 s

An enum is a fixed set of named constant objects that all look the same. A sealed type is a closed set of subclasses that can each have different fields and many instances. Use enum for simple constants, sealed for varied data.

open as a page

Where are subtypes of a sealed class or interface allowed to be declared? Explain the same-module / same-package permitted-subtype rule.

level: middleimportance: must knowfreq 65%
basics
~20 s

Direct subtypes must be in the same module as the sealed declaration, and in the same package. You can nest them inside the sealed type or put them in separate top-level files, as long as they stay in that module and package.

open as a page

What does it mean for a Kotlin @JvmInline value class to be "boxed," and when does the compiler keep it inlined (unboxed) instead?

level: juniorimportance: must knowfreq 55%
basics
~20 s

Normally the value class disappears and only its single wrapped value is used directly, which is fast. Sometimes Kotlin must wrap it back into a real object (boxing), like when it is null or stored generically.

open as a page

What is a Kotlin value class, and why must it be annotated with @JvmInline on the JVM?

level: juniorimportance: must knowfreq 70%
basics
~20 s

A value class wraps one value (like a String or Int) in a new type without the cost of a real object. On the JVM you add @JvmInline so Kotlin can store just the wrapped value instead of a wrapper object.

open as a page

Why would you wrap a String or Long in a value class such as UserId or Email instead of using the raw primitive type directly?

level: juniorimportance: must knowfreq 70%
basics
~20 s

To make the type meaningful and safe. A plain String could be anything; a UserId can only be a user id, so the compiler stops you from mixing up a user id with an order id or an email.

open as a page

At runtime, how does the Kotlin compiler represent a @JvmInline value class, and what does the underlying property's type have to be?

level: middleimportance: must knowfreq 55%
basics
~10 s

Where possible the compiler throws away the wrapper and uses the wrapped value directly, so there's no extra object. The single property can hold almost any type, including another value class.

open as a page

What are the structural constraints on a value class — how many properties can it have, and can it have ordinary properties with backing fields?

level: middleimportance: must knowfreq 60%
basics
~10 s

A value class must have exactly one value (one constructor property). It can't have extra stored properties — only computed ones. That single value is what it really is underneath.

open as a page

How do you declare an enum class in Kotlin, and what is an enum constant?

level: juniorimportance: must knowfreq 80%
basics
~10 s

Write enum class Name { A, B, C }. Each capitalized name inside the braces (A, B, C) is a constant — a fixed, named instance of that enum that you reference as Name.A.

open as a page

In Kotlin, how do you make each enum constant run its own different code for the same operation? Show a small example.

level: juniorimportance: must knowfreq 55%
basics
~10 s

Declare an abstract function in the enum, then give each constant a body in curly braces that overrides it. Calling the function on a constant runs that constant's version.

open as a page

What is the `entries` property on a Kotlin enum class, and how does it differ from the older `values()` function?

level: juniorimportance: must knowfreq 70%
basics
~10 s

entries gives you all the constants of an enum as a read-only list. The old values() did the same but returned an array, and it made a brand-new copy every time you called it.

open as a page

How does a Kotlin enum class implement an interface, and how can the implementation differ per enum constant?

level: juniorimportance: must knowfreq 55%
basics
~10 s

Put the interface name after a colon in the enum header. You can implement the interface once for all constants, or let each constant override the method with its own version inside its body.

open as a page

How do you give each enum constant constructor parameters, and how are those values supplied per constant?

level: middleimportance: must knowfreq 70%
basics
~10 s

Add a constructor to the enum class, then put the argument values in parentheses after each constant, like RED(0xFF0000). Each constant supplies its own values, and you read them as normal properties.

open as a page

How do you create a class whose only way to be constructed is through a named factory function on its companion object, hiding the real constructor?

level: juniorimportance: must knowfreq 70%
basics
~10 s

Mark the constructor private and add a function in the companion object that creates and returns the instance. Callers use the named function instead of calling the constructor directly.

open as a page

What is a companion object in Kotlin, and how do you call its members?

level: juniorimportance: must knowfreq 80%
basics
~10 s

It is a special object declared inside a class with the 'companion object' keywords. Its properties and functions can be called using the class name directly, without creating an instance.

open as a page

What does an `object` declaration create in Kotlin, and how is it different from a regular `class`?

level: juniorimportance: must knowfreq 80%
basics
~10 s

An object declaration creates a singleton: exactly one instance that Kotlin makes for you. You never call a constructor. You use it by its name, like Counter.next().

open as a page

What is a Kotlin object expression (anonymous object), and when would you use one instead of a named class?

level: juniorimportance: must knowfreq 70%
basics
~20 s

An object expression creates a one-off, unnamed instance on the spot, often to implement an interface like a click listener. You use it when you need a single instance and don't want to write a whole named class.

open as a page

When is an `object` declaration initialized, and what guarantees does Kotlin give about thread-safety of that initialization?

level: middleimportance: must knowfreq 65%
basics
~10 s

The object is created the first time something accesses it, not at program start. Kotlin makes sure this happens only once even if many threads hit it at the same time.

open as a page

What is an abstract class in Kotlin, and how do you declare an abstract member that subclasses must implement?

level: juniorimportance: must knowfreq 80%
basics
~10 s

An abstract class is one you cannot create objects from directly. It can have members marked abstract that have no body, and any non-abstract subclass must provide their implementation.

open as a page

A class implements two interfaces that both provide a default implementation of the same method foo(). What does Kotlin require you to do, and why won't it compile otherwise?

level: juniorimportance: must knowfreq 55%
basics
~10 s

Both interfaces give a body for the same method, so Kotlin can't pick one for you. You must override the method in your class. Otherwise the compiler reports an error and refuses to build.

open as a page

In Kotlin, can an interface provide a default implementation for a method? Show how and explain what a class gets when it implements that interface.

level: juniorimportance: must knowfreq 70%
basics
~10 s

Yes. A Kotlin interface method can include a body. Classes that implement the interface inherit that body for free and only need to override it if they want different behavior.

open as a page

In Kotlin, are classes open for subclassing by default? What do you write to allow a class to be subclassed?

level: juniorimportance: must knowfreq 85%
basics
~10 s

No. By default Kotlin classes are final, so you cannot extend them. To allow subclassing you mark the class with the open keyword.

open as a page

In Kotlin, why is the `override` keyword mandatory when redefining a member from a superclass or interface, and what happens if you omit it?

level: juniorimportance: must knowfreq 75%
basics
~10 s

You must write override before a function or property that replaces one from the parent. It makes your intent explicit. If you forget it, the code does not compile.

open as a page

What does the `by` keyword do when a class declares `class MyList(impl: List<String>) : List<String> by impl`?

level: juniorimportance: must knowfreq 55%
basics
~10 s

It makes the class implement the List interface by automatically forwarding every interface method call to the impl object you pass in, so you don't write those methods by hand.

open as a page

In Kotlin, what does it mean to implement an interface 'by' delegating to another object, and why might you prefer that over extending an open base class?

level: juniorimportance: must knowfreq 65%
basics
~20 s

The 'by' keyword lets a class implement an interface by handing every method call to another object you give it. You reuse behavior by wrapping an object instead of subclassing it, so you don't depend on a parent class's internals.

open as a page

When you override a member in a class that uses `by` delegation, do the OTHER auto-forwarded members start calling your override or the delegate's own implementation? Explain the trap.

level: middleimportance: must knowfreq 55%
basics
~20 s

Other forwarded methods still call the delegate's own versions, not your override. The delegate doesn't know about your wrapper, so any internal calls it makes go to itself. Your override only affects calls made directly on the wrapper.

open as a page

When you write `class W(impl: Foo) : Foo by impl`, is the `impl` value stored and accessible inside the class? How do you access the delegate if you need it?

level: middleimportance: should knowfreq 35%
basics
~10 s

The compiler stores the delegate in a hidden field, but a plain constructor parameter is not a property, so you can't reference it later. To use it inside the class, declare it as val.

open as a page

In a class using interface delegation, if you both delegate to an object and explicitly override one method, which implementation runs — and does the delegate still see the override?

level: middleimportance: should knowfreq 45%
basics
~10 s

Your explicit override always runs for that method. But the delegate object never knows about your override — if it calls another of its own methods internally, it calls its own version, not yours.

open as a page