Kotlin object expressions and object declarations


Release date:2023-09-26 Update date:2023-10-13 Editor:admin View counts:5349

Label:

Kotlin object expressions and object declarations

Kotlin use object expressions and object declarations to create an object of a class that has made minor changes to a class without declaring anew subclass.

Object expression

An object of an anonymous inner class is implemented through an object expression in the parameters of the method:

window.addMouseListener(object : MouseAdapter() {
    override fun mouseClicked(e: MouseEvent) {
        // ...
    }
    override fun mouseEntered(e: MouseEvent) {
        // ...
    }
})

Objects can inherit from a base class or implement other interfaces:

open class A(x: Int) {
    public open val y: Int = x
}

interface B {……}

val ab: A = object : A(1), B {
    override val y = 15
}

If the supertype has a constructor, you must pass parameters to it. Multiple supertypes and interfaces can be separated by commas.

Through the object expression, you can get an object directly beyond the definition of the class:

fun main(args: Array<String>) {
    val site = object {
        var name: String = "Novice Tutorial"
        var url: String = "www.runoob.com"
    }
    println(site.name)
    println(site.url)
}

Note that anonymous objects can be used as types declared only locally and in private scopes. If you use an anonymous object as the return type of a public function or a type used as a public property, then the actual type ofthe function or property will be a supertype declared by the anonymous object, or Any if you do not declare any hypertypes. Members added to anonymous objects will not be accessible.

class C {
    // Private function, so its return type is anonymous object type
    private fun foo() = object {
        val x: String = "x"
    }

    // Public function, so its return type is Any
    fun publicFoo() = object {
        val x: String = "x"
    }

    fun bar() {
        val x1 = foo().x        // No problem
        val x2 = publicFoo().x  // Error: Unresolved reference 'x'
    }
}

Other variables in the scope can be easily accessed in the object representation:

fun countClicks(window: JComponent) {
    var clickCount = 0
    var enterCount = 0

    window.addMouseListener(object : MouseAdapter() {
        override fun mouseClicked(e: MouseEvent) {
            clickCount++
        }

        override fun mouseEntered(e: MouseEvent) {
            enterCount++
        }
    })
    // ……
}

Object declaration

Kotlin use object keyword to declare an object.

Kotlin can easily get a singleton through object declaration.

object DataProviderManager {
    fun registerDataProvider(provider: DataProvider) {
        // ……
    }

    val allDataProviders: Collection<DataProvider>
        get() = // ……
}

By referencing the object, we can simply use its name:

DataProviderManager.registerDataProvider(……)

Of course, you can also define a variable to get the object, and when you define two different variables to get the object, you will find that you can’t get two different variables. In other words, in this way, we get a singleton.

var data1 = DataProviderManager
var data2 = DataProviderManager
data1.name = "test"
print("data1 name = ${data2.name}")

Example

In the following example, both objects output the same url address:

object Site {
    var url:String = ""
    val name: String = "Novice Tutorial"
}
fun main(args: Array<String>) {
    var s1 =  Site
    var s2 = Site
    s1.url = "www.runoob.com"
    println(s1.url)
    println(s2.url)
}

The output is as follows:

www.runoob.com
www.runoob.com

Objects can have supertypes:

object DefaultListener : MouseAdapter() {
    override fun mouseClicked(e: MouseEvent) {
        // ……
    }

    override fun mouseEntered(e: MouseEvent) {
        // ……
    }
}

Unlike an object expression, when an object is declared inside another class, the object cannot be accessed through an instance of the external class, but only through the class name. Similarly, the object does not have direct access to the methods and variables of the external class.

class Site {
    var name = "Novice Tutorial"
    object DeskTop{
        var url = "www.runoob.com"
        fun showName(){
            print{"desk legs $name"} // Error,
             unable to access methods and variables of external classes
        }
    }
}
fun main(args: Array<String>) {
    var site = Site()
    site.DeskTop.url // Error, cannot access this object through an
     instance of an external class
    Site.DeskTop.url // correct
}

Associated object

The object declaration within the class can be used with the companion keyword tag so that it is associated with the external class so that we can access the internal elements of the object directly through the external class.

class MyClass {
    companion object Factory {
        fun create(): MyClass = MyClass()
    }
}

val instance = MyClass.create()   // Accessing internal elements of an object

We can omit the object name of the object and replace the object name that needs to be declared with Companion:

class MyClass {
    companion object {
    }
}

val x = MyClass.Companion

Note: only one internally related object, namely keyword, can be declared ina class, companion can only be used once.

Let the members of the accompanying object look like static members of otherlanguages, but they are still instance members of the real object at run time. For example, you can also implement an interface:

interface Factory<T> {
    fun create(): T
}


class MyClass {
    companion object : Factory<MyClass> {
        override fun create(): MyClass = MyClass()
    }
}

Semantic differences between object expressions and object declarations

There is an important semantic difference between object expressions and object declarations:

  • Object expressions are executed immediately where they are used

  • The object declaration is delayed initialization when it is first accessed

  • The initialization of the accompanying object matches the semantics of the Java static initializer when the corresponding class is loaded (parsed).

Powered by TorCMS (https://github.com/bukun/TorCMS).