ProgrammingKotlin Developer

Explain the nuances of constructor visibility and inheritance in Kotlin: what are the differences between primary and secondary constructors, nuances with inheritance and visibility modifiers. Provide code examples and typical mistakes.

Pass interviews with Hintsage AI assistant

Answer.

In Kotlin, any class can have one primary constructor (declared in the class declaration) and multiple secondary constructors (with constructor).

  • The primary constructor cannot contain code outside the declaration (logic is in init).
  • Secondary constructors implement additional initialization options.
  • If the parent does not have a no-argument constructor, the child must explicitly call its constructor.
  • With modifiers (private, protected, internal, public), you can hide or limit the visibility of constructors.

Example with primary and secondary constructors:

open class Person(val name: String) { constructor(name: String, age: Int) : this(name) { // secondary constructor } } class Employee : Person { constructor(name: String) : super(name) // Explicit super call is required }

Visibility modifiers:

class Secret private constructor() { companion object { fun create() = Secret() } } val s = Secret.create() // Ok, but Secret() - error

Nuances:

  • If a class with a primary constructor has parameters, it is impossible to inherit without passing these parameters.
  • Secondary constructors must indirectly or directly call the primary one.
  • Nested classes do not have access to the private constructor of the outer class.

Trick question.

Is it possible to inherit a class in Kotlin and not call its primary constructor?

Answer: No. In Kotlin, when inheriting, at least one parent constructor must always be called — either the primary or a secondary one (via super()).

Example:

open class A(val x: Int) class B: A // Error: A's constructor must be explicitly called

Examples of real mistakes due to ignorance of the topic's nuances.


Story

The team tried to prevent the direct creation of objects of a class and made the constructor private. However, they forgot to implement the factory method. This led to the inability to test the class without reflection and blocked the CI.


Story

Inherited a class with mandatory parameters in the primary constructor but did not pass them when declaring the subclass. This was only discovered at compile time after long debugging.


Story

When using secondary constructors, they forgot that all of them must call the primary one. As a result, objects were initialized without necessary parameters, leading to NullPointerException at runtime.