How do you implement a Factory interface on a companion object, and why is that useful?
answer
- companion object : Factory<T>
- companion is a real object → can implement interfaces
- pass ClassName.Companion as a Factory value
- registries / DI without reflection
- Factory<out T> enables variance
basics
~20 sA companion object is a real object, so it can implement an interface. You write companion object : Factory<T> and override the interface's create function. Now the class's companion can be passed around as a Factory value.
solid answer
~40 sBecause a `companion object` is an actual object instance (not just static slots), it can extend a superclass or implement interfaces. You declare `companion object : Factory<MyType> { override fun create(...) = MyType(...) }`. This means the companion itself is a value of type `Factory<MyType>`, so you can pass `MyType.Companion` (or `MyType` where the companion is implied) wherever a `Factory<MyType>` is expected — useful for plugging classes into generic creation frameworks, registries, or dependency-injection wiring without reflection. The interface gives a uniform, type-safe `create` contract across many types, and each class supplies its own construction logic in its companion. You can reference the companion explicitly as `MyType.Companion` or by the class name when context expects the companion.
code
kotlin · 12 linesinterface Factory<out T> { fun create(): T }
class Widget private constructor(val n: Int) {
companion object : Factory<Widget> {
private var next = 0
override fun create(): Widget = Widget(next++)
}
}
fun <T> repeatCreate(f: Factory<T>, times: Int) = (1..times).map { f.create() }
val widgets = repeatCreate(Widget, 3) // Widget.Companion passed as Factory<Widget>go deeper
Recognizes the companion object : Interface syntax and that you override the interface method.
Explains that the companion is a real object passable as the interface type and gives a registry/DI use case.
Adds variance (out T), combines interface hook with named factories, and discusses reflection-free plugin registries.
Designs an extensible creation SPI where companions register as factories, weighing variance, binary compatibility, and discoverability trade-offs.
## The key fact A Kotlin `companion object` is a genuine singleton **object instance** attached to the class — not merely Java-style static members. Therefore it can do everything an object can: implement interfaces and extend an open class. ## Defining a Factory interface and implementing it ```kotlin interface Factory<out T> { fun create(): T } class Connection private constructor(val id: Int) { companion object : Factory<Connection> { private var counter = 0 override fun create(): Connection = Connection(counter++) } } ``` Now `Connection.Companion` is a `Factory<Connection>`. You can store it, pass it, and call it polymorphically: ```kotlin fun <T> buildTwo(factory: Factory<T>): List<T> = listOf(factory.create(), factory.create()) val conns = buildTwo(Connection) // companion is passed as the Factory ``` When the expected type is the companion's interface, you can pass the **class name** (`Connection`) and Kotlin resolves it to `Connection.Companion`; otherwise reference it explicitly as `Connection.Companion`. ## Why this is useful - **Uniform, type-safe creation contract** across many unrelated classes — each class carries its own factory in its companion. - **Registries / plugin systems**: a `Map<String, Factory<Base>>` can map keys to companions, choosing an implementation at runtime without reflection. - **Generic frameworks / DI**: pass a companion as a creation strategy. - **`out` variance** (`Factory<out T>`) lets a `Factory<Sub>` be used as a `Factory<Super>`. ## Combining with a named factory and private constructor You can have both: an interface-driven `create()` plus extra named factories (`fromConfig(...)`) and a `private constructor` so the companion is the only construction path. The interface method gives a polymorphic hook; the named functions give ergonomic, validated entry points. ## Gotchas - The companion's interface members are part of the companion's type, accessed via the companion, not as plain static-looking calls unless the call site expects the interface. - A class has at most one companion object, so all factory interfaces it implements live on that single companion.
- How do you reference the companion explicitly when you need it as the interface type?Use `ClassName.Companion`. Where the call site already expects the interface, you can pass just `ClassName` and Kotlin resolves it to the companion.
- Can a class implement two different factory interfaces this way?Yes — a class has one companion, and that single companion can implement multiple interfaces, as long as their members don't conflict.
The companion acting as a Factory is like a car model's official dealership: there's exactly one per model, and it satisfies the generic 'sells cars' contract so any buyer can use it interchangeably.
saying these in an interview costs you the question
- Saying a companion can't implement interfaces because it's 'just static'
- Thinking you need reflection to use a class as a factory
- Believing each factory interface needs its own companion (only one companion allowed)
- Confusing the companion (instance) with the class itself