Kotlin: Разница между объектом и сопутствующим объектом в классе
В чем разница между объектом и сопутствующим объектом в классе в kotlin?
Пример:
class MyClass {
object Holder {
//something
}
companion object {
//something
}
}
Я уже прочитал, что используется объект-компаньон, если содержащиеся параметры/методы тесно связаны с его классом.
Но почему существует возможность объявления нормального объекта в классе? Поскольку он ведет себя точно так же, как и компаньон, но он должен иметь имя.
Есть ли разница в его статическом (со стороны Java) жизненном цикле?
Ответы
Ответ 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 нижний раздел четко определяет разницу между этими двумя.