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

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

пример:

class MyClass {

    object Holder {
        //something
    }

    companion object {
        //something
    }
}

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

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

может быть, есть разница в его "статический" (я со стороны java) жизненный цикл?

4 ответов


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

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


существует два разных типа 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 к объявлению объекта позволяет добавлять" статическую " функциональность к объекту, даже если фактическая статическая концепция не существует в Котлин. Вот пример класса с методами экземпляра и методами-компаньонами.

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

       fun instanceMethod() {
            // do stuff
        }
    }

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

    var myClass = MyClass()
    myClass.instanceMethod()

вызов метода companion object будет выглядеть следующим образом.

    MyClass.actsAsStatic()

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


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

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


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