Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the advantages of a companion object over a plain object?

Tags:

kotlin

Kotlin code like this:

class Foo {
  companion object {
     fun a() : Int = 1
  }
  fun b() = a() + 1
}

can trivially be changed to

object FooStatic {
   fun a() : Int = 1
}

class Foo {
  fun b() = FooStatic.a()
}

I'm aware that the companion object can be used to allow use as real java static function, but are there any other advantages to using the companion object?

like image 578
Michael Anderson Avatar asked Nov 01 '17 00:11

Michael Anderson


People also ask

What is the benefit of companion object?

Advantages of Companion Objects in Scala Companion objects provide a clear separation between static and non-static methods in a class because everything that is located inside a companion object is not a part of the class's runtime objects but is available from a static context and vice versa.

What is difference between companion object and object?

A Companion object is initialized when the class is loaded (typically the first time it's referenced by other code that is being executed) whereas Object declarations are initialized lazily, when accessed for the first time.

When should I use companion object?

companion object for factory functions Notice how the constructor is kept private but the companion object has access to the constructor . This is useful when you want to provide multiple ways to create an object where the object construction process is complex.

Why do we use companion object in Kotlin?

companion object is how you define static variables/methods in Kotlin. You are not supposed to create a new instance of Retrofit / ApiService each time you execute a request, however.


1 Answers

One of the key differences is visibility of the members. In a companion object, visibility to the containing class is as-if the members were part of the class - this is not the case for a raw object.

The example below shows that you cant use an "object" to implement private static internals of a class.

package com.example

class Boo {

    companion object Boo_Core {
        // Public "static" call that non-Boo classes should not be able to call
        fun add_pub(a:Int) = a+1;

        // Internal "static" call that non-Boo classes should not be able to call
        private fun add_priv(a:Int) = a+1;
    }

    // OK: Functions in Boo can call the public members of the companion object
    fun blah_pub(a:Int) = add_pub(a)
    // OK: Functions in Boo can call the private members of the companion object
    fun blah_priv(a:Int) = add_priv(a)
}

//Same idea as the companion object, but as an "object" instead.
object Foo_Core {
    fun add_pub(a:Int) = a+1
    private fun add_priv(a:Int) = a+1;
}

class Foo {
    // OK Foo can get Foo_Cors add_pub
    fun blah_pub(a:Int) = Foo_Core.add_pub(a);

    // ERROR: can not get to add_priv
    // fun blah_priv(a:Int) = Foo_Core.add_priv(a);
}

class AnInterloper {

    // OK Other classes can use public entries in Foo.
    fun blah_foo_pub(a:Int) = Foo_Core.add_pub(a); 

    // ERROR Other classes can use public entries in Foo.
    // fun blah_foo_priv(a:Int) = Foo_Core.add_priv(a); 

    // OK: Other classes can use public Boo classes
    fun blah_boo_pub(a:Int) = Boo.add_pub(a);

    // ERROR: Other classes can not use private Boo classes
    // fun blah_boo_priv(a:Int) = Boo.add_priv(a);
}
like image 67
Michael Anderson Avatar answered Oct 20 '22 00:10

Michael Anderson