When to use
- When you want to create an object with small changes of the class without having to explicitly declare the subclass of that class.
Object expression
- Creates an object of an anonymous class that inherits from one or more other types. Such an object is called an anonymous object (the side name is anonymous object), the syntax:12345window.addMouseListener(object : MouseAdapter() {override fun mouseClicked(e: MouseEvent) { /*...*/ }override fun mouseEntered(e: MouseEvent) { /*...*/ }})
If the parent type has a constructor, the appropriate parameters must be passed to that constructor. If there are multiple types father inherited / deployment, they are separated by a semicolon separated,
:12345678910open class A(x: Int) {public open val y: Int = x}interface B { /*...*/ }val ab: A = object : A(1), B {override val y = 15}
If only objects are needed, not parent type:12345678fun foo() {val adHoc = object {var x: Int = 0var y: Int = 0}print(adHoc.x + adHoc.y)} - Anonymous object can be used as a type only if local and
private
declarations. - If an anonymous object is used as the return type of the
public
or the declared type ofpublic
properties, the actual type of that method / property will be specified as the type of the parent of the anonymous object or isAny
if no parent type has been declared before. And the component added in the anonymous object will be inaccessible:1234567891011121314151617class C {// Private function, so the return type is the anonymous object typeprivate fun foo() = object {val x: String = "x"}// Public function, so the return type is Anyfun publicFoo() = object {val x: String = "x"}fun bar() {val x1 = foo().x // Worksval x2 = publicFoo().x // ERROR: Unresolved reference 'x', because anonymous object is used as return type of publicFoo()}} - The code in an object expression can access variables from a range that surrounds the object expression :12345678910111213141516fun countClicks(window: JComponent) {var clickCount = 0var enterCount = 0window.addMouseListener(object : MouseAdapter() {override fun mouseClicked(e: MouseEvent) {clickCount++}override fun mouseEntered(e: MouseEvent) {enterCount++}})// ...}
Object declaration
- Singleton partern can be useful in many cases, declaring singleton in Kotlin is very easy like this:123456789object DataProviderManager {fun registerDataProvider(provider: DataProvider) {// ...}val allDataProviders: Collection<DataProvider>get() = // ...}
The declarationDataProviderManager
as above is the declaration object , and it always has a defined name after theobject
keyword. - Like declaring a variable, a
object declaration
is not an expression, and cannot be used on the right side of an assignment. - To refer to the object, use its name directly:
DataProviderManager.registerDataProvider(...)
- These objects can have parent type123456object DefaultListener : MouseAdapter() {override fun mouseClicked(e: MouseEvent) { ... }override fun mouseEntered(e: MouseEvent) { ... }}
- Object daclaration cannot be
local
(eg in a method), but it can be declared in another daclaration object or a non-inner class.
Companion object
- The declaration object inside a class can be marked with the
companion
keyword:123456class MyClass {companion object Factory {fun create(): MyClass = MyClass()}} - Companion object components can be called by separating the class name:
val instance = MyClass.create()
- There is a tag that does not need to declare the name of companion object , in this case the name
Companion
will be used:123456class MyClass {companion object { }}val x = MyClass.Companion - Although companion object components seem like
static
components in other languages, at runtime they are still and instances of an actual object and can do a number of things, such as implementing interfaces:123456789101112interface Factory<T> {fun create(): T}class MyClass {companion object : Factory<MyClass> {override fun create(): MyClass = MyClass()}}val f: Factory<MyClass> = MyClass - However, companion object components can be created as
static
methods andstatic
fields if using JvmStatic annotation.
Difference
- Some important differences between object expression and declaration object :
- Object expression is executed and instantiated as soon as it is used.
- The Object declaration is initialized late when the object is first accessed.
- Companion object is instantiated when the corresponding class is uploaded,