Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Companion objects benefits of posibility to implement interfaces

Why in Kotlin/Scala companion objects can implements some interfaces, what benefits this can have? When is useful to use this feature?

like image 362
Axel Avatar asked Oct 20 '25 16:10

Axel


2 Answers

You can use companion objects and inheritance for some level of class-lavel or static polymorphism.

Example 1: Factories

Consider an interface

interface Factory<T> {
    fun create(): T
}

Now, we create a class whose companion object implements it

class Foo {
    companion object: Factory<Foo> {
        override fun create() = Foo()
    }
}

Now we can create an extension function for all factories to create and e.g. log the object.

fun <T> Factory<T>.createAndLog(): T {
    val t = create()
    println(t)
    return t
}

Und use it like so

Foo.createAndLog()

Example 2: Queries

Consider a marker interface

interface Queryable<T>

We now have two classes User and Article that represent tables in a database whose companion object implements the interface.

class User(val id: String) {
    companion object: Queryable<User> {}
}

class Article(val authorId: String) {
    companion object: : Queryable<Article> {}
}

We can now define an extension function to create a query from the class

fun <T> Queryable<T>.query() = db.createQuery<T>()

which we can call as

User.query()
//or
Article.query()
like image 178
Kirill Rakhman Avatar answered Oct 23 '25 07:10

Kirill Rakhman


Because companion objects are objects, objects can implement interfaces (or extend classes), and there is no good reason to disallow it for companion objects in particular.

One common use in Scala is for factories: e.g. Seq, List, Vector etc. companion objects all extend TraversableFactory so you can write code working with a TraversableFactory and pass any of them to construct the type you want. E.g.

def build[CC[X] <: Traversable[X] with GenericTraversableTemplate[X, CC], A](factory: TraversableFactory[CC])(elems: A*) = factory(elems)

// build(List)(1,2,3) == List(1, 2, 3)
// build(Set)(1,2,3) == Set(1, 2, 3)

Similarly, all case class companion objects extend function types.

like image 22
Alexey Romanov Avatar answered Oct 23 '25 07:10

Alexey Romanov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!