Каковы преимущества сопутствующего объекта над простым объектом?

Код Котлина:

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

можно тривиально изменить на

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

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

Я знаю, что объект-компаньон можно использовать для использования в качестве реальной статической функции java, но есть ли другие преимущества для использования объекта-компаньона?

Ответ 1

Одним из ключевых различий является видимость членов. В сопутствующем объекте видимость для содержащего класса такая, как если бы члены были частью класса - это не относится к необработанному объекту.

В приведенном ниже примере показано, что вы не можете использовать "объект" для реализации частных статических внутренних элементов класса.

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);
}