Подтвердить что ты не робот

Kotlin: Разница между объектом и сопутствующим объектом в классе

В чем разница между объектом и сопутствующим объектом в классе в kotlin?

Пример:

class MyClass {

    object Holder {
        //something
    }

    companion object {
        //something
    }
}

Я уже прочитал, что используется объект-компаньон, если содержащиеся параметры/методы тесно связаны с его классом.

Но почему существует возможность объявления нормального объекта в классе? Поскольку он ведет себя точно так же, как и компаньон, но он должен иметь имя.

Есть ли разница в его статическом (со стороны Java) жизненном цикле?

4b9b3361

Ответ 1

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

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

Ответ 2

Существует два различных типа использования object: выражение и объявление.

Выражение объекта

Выражение объекта может использоваться, когда класс нуждается в небольшой модификации, но нет необходимости создавать для него совершенно новый подкласс. Анонимные внутренние классы являются хорошим примером этого.

    button.setOnClickListener(object: View.OnClickListener() {
        override fun onClick(view: View) {
            // click event
        }
    })

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

Объявление объекта

Объявление объекта аналогично объявлению переменной и поэтому не может использоваться справа от оператора присваивания. Объявления объектов очень полезны для реализации шаблона Singleton.

    object MySingletonObject {
        fun getInstance(): MySingletonObject {
            // return single instance of object
        }
    }

И тогда метод getInstance может быть вызван следующим образом.

    MySingletonObject.getInstance()

Сопутствующий объект

Сопутствующий объект - это определенный тип объявления объекта, который позволяет объекту действовать подобно статическим объектам в других языках (таких как Java). Добавление companion к объявлению объекта позволяет добавить "статическую" функциональность к объекту, даже если фактическая статическая концепция не существует в Kotlin. Вот пример класса с методами экземпляра и сопутствующими методами.

 class MyClass {
        companion object MyCompanionObject {
            fun actsAsStatic() {
                // do stuff
            }
        }

       fun instanceMethod() {
            // do stuff
        }
    }

Вызов метода экземпляра будет выглядеть следующим образом.

    var myClass = MyClass()
    myClass.instanceMethod()

Вызов метода сопутствующего объекта будет выглядеть следующим образом.

    MyClass.actsAsStatic()

См. Kotlin документы для получения дополнительной информации.

Ответ 3

Объект или объявление объекта инициализируется лениво при первом доступе.

Сопутствующий объект инициализируется при загрузке соответствующего класса. Это приводит к "статической" сущности, хотя Kotlin по своей сути не поддерживает статические члены.

Ответ 4

Объект Companion существует, потому что вы можете вызвать функции/свойства сопутствующих объектов, такие как статический метод/поле java. И почему ваш Holder разрешен, ну, нет причин, чтобы объявление вложенного объекта было незаконным. Иногда это может пригодиться.

Ответ 5

Объект Companion инициализируется при загрузке класса (обычно это первый раз, когда на него ссылается другой выполняемый код), тогда как объявления объекта инициализируются лениво при первом обращении к нему.

Пожалуйста, обратитесь https://kotlinlang.org/docs/reference/object-declarations.html нижний раздел четко определяет разницу между этими двумя.