3.17. Kotlin object expressions and object declarations

发布时间 : 2025-10-25 13:34:26 UTC      

Page Views: 10 views

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.

3.17.1. 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++ } }) // …… } 

3.17.2. 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 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}") 

3.17.3. 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 } 

3.17.4. 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() } } 

3.17.5. 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).

《地理信息系统原理、技术与方法》  97

最近几年来,地理信息系统无论是在理论上还是应用上都处在一个飞速发展的阶段。 GIS被应用于多个领域的建模和决策支持,如城市管理、区划、环境整治等等,地理信息成为信息时代重要的组成部分之一; “数字地球”概念的提出,更进一步推动了作为其技术支撑的GIS的发展。 与此同时,一些学者致力于相关的理论研究,如空间感知、空间数据误差、空间关系的形式化等等。 这恰好说明了地理信息系统作为应用技术和学科的两个方面,并且这两个方面构成了相互促进的发展过程。