Object expressions and object declarations
Kotlin uses object expressions and object declarations to create an object of a class that has made minor changes to a class, and there is no need to declare a new subclass.
Object expression
Implement an object of an anonymous inner class through an object expression and use it 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 object expression, you can directly get an object across the definition of the class:
fun main(args: Array<String>) { val site = object { var name: String = "Rookie tutorial" var url: String = "www.runoob.com" } println(site.name) println(site.url) }
Note that anonymous objects can be used as types declared only in local and private scopes. If you use an anonymous object as the return type of a public function or as the type of a public property, the actual type of the function or property will be the supertype declared by the anonymous object. If you do not declare Any supertype, it will be Any. 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: failed to resolve reference 'x' for } }
You can easily access other variables in the scope 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 uses the object keyword to declare an object.
In Kotlin, we can easily obtain a singleton through object declaration.
object DataProviderManager { fun registerDataProvider(provider: DataProvider) { // ...... } val allDataProviders: Collection<DataProvider> get() = // ...... }
To reference this object, we can directly use its name:
DataProviderManager.registerDataProvider(......)
Of course, you can also define a variable to get the object. When you define two different variables to get the object, you will find that you can't get two different variables. That is, in this way, we get a single example.
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 = "Rookie 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 result is:
www.runoob.com www.runoob.com
Objects can have supertypes:
object DefaultListener : MouseAdapter() { override fun mouseClicked(e: MouseEvent) { // ...... } override fun mouseEntered(e: MouseEvent) { // ...... } }
Unlike object expressions, when an object is declared inside another class, the object cannot be accessed through the instance of the external class, but only through the class name. Similarly, the object cannot directly access the methods and variables of the external class.
class Site { var name = "Rookie 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, the object cannot be accessed through an instance of an external class Site.DeskTop.url // correct }
Companion Object
The object declaration inside the class can be marked with the company keyword, so it is associated with the external class, and we can directly access the internal elements of the object 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 then use Companion instead of the object name to be declared:
class MyClass { companion object { } } val x = MyClass.Companion
**Note: * * only one internal association object can be declared in a class, that is, the keyword company can only be used once.
Make sure that the members of the companion object look like static members of other languages, but they are still instance members of the real object at run time. For example, you can also implement interfaces:
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
- Object declarations delay initialization when first accessed
- The initialization of the associated object matches the semantics of the Java static initializer when the corresponding class is loaded (parsed)