SoFunction
Updated on 2025-04-12

Specific use of object expressions and object declarations in Kotlin

The main difference between Kotlin's object expression and anonymous inner classes in Java: anonymous inner classes can only specify one parent type, but object expressions can specify 0~N skin types.

1. Object expression

The syntax format of object expressions is as follows:

object [: 0~NParent type]{
  //The body part of the object expression}

There are also the following rules for object expressions:

  • Object expressions cannot be abstract classes, because the system creates objects immediately when creating object expressions. Therefore, object expressions are not allowed to be defined as abstract classes.
  • Object expressions cannot define constructors. But object expressions can define initialization blocks, and the constructor needs to complete what it needs to do by initializing blocks.
  • Object expressions can contain inner classes, not nested classes.
package `0705`

interface Outputable {
  fun output(msg: String)
}

abstract class Product(var price: Double) {
  abstract val name: String
  abstract fun printInfo()
}

fun main(args: Array<String>) {
  //Specify an object expression of parent type (interface)  var ob1 = object : Outputable {
    override fun output(msg: String) {
      for (i in 1..6) {
        println("<h${i}>${msg}</h${i}>")
      }
    }
  }
  ("Export something casually")
  println("-----------------------------------------------")
  //Specify zero parent type object expression  var ob2 = object {
    //Initialize block    init {
      println("Initialization Block")
    }

    //property    var name = "Kotlin"

    //method    fun test() {
      println("test method")
    }

    //Only include inner classes, not nested classes    inner class Inner
  }
  println()
  ()
  println("-----------------------------------------------")
  //Specify two parent type object expressions  var ob3 = object : Outputable, Product(1.23) {
    override fun output(msg: String) {
      println("Output information:${msg}")
    }

    override val name: String
      get() = "Laser Printer"

    override fun printInfo() {
      println("High-speed aurora printers support automatic double-sided printing!")
    }
  }
  println()
  ("Kotlin learns slowly")
  ()
}

Output result:

<h1>Export something casually</h1>
<h2>Export something casually</h2>
<h3>Export something casually</h3>
<h4>Export something casually</h4>
<h5>Export something casually</h5>
<h6>Export something casually</h6>
-----------------------------------------------
Initialize block
Kotlin
Test method
-----------------------------------------------
Laser printer
Output information: Kotlin learns slowly
High-speed aurora printers support automatic double-sided printing!

Kotlin's object expression can be divided into two situations:

  • Object expressions are within the local scope of the method, or object expressions modified with private, the Kotlin compiler can recognize the real type of object expressions.
  • Non-private modified object expressions are similar to Java's anonymous internal classes. The compiler will only treat object expressions as its inherited parent class or implemented interface. If it does not have a parent type, the system is when it is of Any type.
package `0705`

class ObjectExprType {
  private val ob1 = object {
    val name: String = "Kotlin"
  }
  internal val ob2 = object {
    val name: String = "Kotlin"
  }
  private fun privateBar()=object {
    val name:String="Java"
  }
  fun publicBar()=object {
    val name:String="Java"
  }
  fun test(){
    //ob1 is a private object expression, and the compiler can recognize its real type    println()
    //ob2 is a non-private object expression, the compiler is when it is of Any type//    println()
    //privateBar is a private function, and the compiler can recognize the real type of the object expression it returns    println(privateBar().name)
    //publicBar is a non-private function. The compiler treats the object expression it returns as Any type//    println(publicBar().name)
  }
}

fun main(args: Array&lt;String&gt;) {
  ObjectExprType().test()
}

Output result:

Kotlin
Java

The Kotlin compiler can recognize the real type of private object expression.

Kotlin's object expressions can access or modify local variables within their scope.

fun main(args: Array&lt;String&gt;) {
  var a = 20
  var obj = object {

    fun change() {
      println("change()Method modification to change quantityaValue of")
      a++
    }
  }
  ()
  println(a)
}

Output result:

Change() method changes the value of the variable a
21

Kotlin's object expressions are enhanced by three aspects than Java's anonymous internal classes:

  • Object expressions can specify multiple parent types
  • The Kotlin compiler can more accurately identify the types of private object expressions in the local scope.
  • Object expressions can access or modify local variables within their scope

2. Object declaration and singleton pattern

The syntax format of object declaration is as follows:

object ObjectName [: 0~NParent type]{
  //The body part of the object expression}

The syntax of object declaration and object expression is very similar, the difference is that the object expression has no name after the object keyword; while the object declaration requires a name after the object keyword.

There are also differences between the two as follows:

  • An object expression is an expression that can be assigned to a variable; while an object declaration is not an expression and cannot be used for assignment.
  • An object declaration can contain nested classes, but cannot contain inner classes; while an object expression can contain inner classes, but cannot contain nested classes.
  • Object declarations cannot be defined within functions and methods; however object expressions can be nested in other object declarations or non-inner classes.
package `0705`

interface Outputable {
  fun output(msg: String)
}

abstract class Product(var price: Double) {
  abstract val name: String
  abstract fun printInfo()
}

//Specify an object expression of parent typeobject MyObject1 : Outputable {
  override fun output(msg: String) {
    for (i in 1..6) {
      println("&lt;h${i}&gt;${msg}&lt;/h${i}&gt;")
    }
  }
}

//Specify zero parent type object expressionobject MyObject2 {
  //Initialize block  init {
    println("Initialization Block")
  }

  //property  var name = "Kotlin"

  //method  fun test() {
    println("test method")
  }

  //Only include nested classes, not internal classes  class Inner
}

//Specify two parent type object expressionsobject MyObject3 : Outputable, Product(1.23) {
  override fun output(msg: String) {
    println("Output information:${msg}")
  }

  override val name: String
    get() = "Laser Printer"

  override fun printInfo() {
    println("High-speed aurora printers support automatic double-sided printing!")
  }
}

fun main(args: Array&lt;String&gt;) {

  ("Learn Kotlin together")
  println("-----------------------------------------------")
  println()
  ()
  println("-----------------------------------------------")
  println()
  ("Kotlin is really good")
  ()
}

Output result:

<h1>Learn Kotlin</h1>
<h2>Learn Kotlin</h2>
<h3>Learn Kotlin</h3>
<h4>Learn Kotlin</h4>
<h5>Learn Kotlin</h5>
<h6>Learn Kotlin</h6>
-----------------------------------------------
Initialize block
Kotlin
Test method
-----------------------------------------------
Laser printer
Output information: Kotlin is really good
High-speed aurora printers support automatic double-sided printing!

Object declarations are specifically used to implement singleton pattern. The object defined by the object declaration is the only instance of the class. The program can directly access the unique instance of the class through the name of the object declaration.

3. Companion objects and static members

The object declaration defined in the class can be modified using companion so that the object becomes a companion object.

Each class can only define at most one companion object. The companion object is equivalent to an object of an external class. The program can directly call members of the companion object through the external class.

package `0705`

interface CompanionTest {
  fun output(msg: String)
}

class MyClass {
  //Companion modified companion object  companion object MyObject1 : CompanionTest {
    val name = "name attribute value"
    override fun output(msg: String) {
      for (i in 1..6) {
        println("&lt;h${i}&gt;${msg}&lt;/h${i}&gt;")
      }
    }
  }
}

fun main(args: Array&lt;String&gt;) {
  //Calling the method of the companion object using the class where the companion object is located  ("Kotlin must be learned")
  println()
}

Output result:

<h1>Kotlin must be learned</h1>
<h2>Kotlin must be learned</h2>
<h3>Kotlin must be learned</h3>
<h4>Kotlin must be learned</h4>
<h5>Kotlin must be learned</h5>
<h6>Kotlin must be learned</h6>
name attribute value

The main function of a companion object is to simulate static members for the external class where it is located, but it is just a simulation. The members of the companion object are still instance members of the companion object itself and do not belong to the external class where the companion object is located.

4. Extension of companion objects

Companion objects can also be expanded. If a class has companion objects, Kotlin allows extending methods and properties for companion objects.

package `0705`

interface CompanionTest {
  fun output(msg: String)
}

class MyClass {
  //Companion modified companion object  companion object : CompanionTest {
    val name = "name attribute value"
    override fun output(msg: String) {
      for (i in 1..6) {
        println("&lt;h${i}&gt;${msg}&lt;/h${i}&gt;")
      }
    }
  }
}

//Extend method for companion objectfun () {
  println("Methods to extend for companion objects")
}

val 
  get() = "Properties that extend for companion objects"

fun main(args: Array&lt;String&gt;) {
  //Calling the method of the companion object using the class where the companion object is located  ("Kotlin must be learned")
  println()
  //Call the members of the extended object by calling the class where the object is located  ()
  println()

}

Output result:

<h1>Kotlin must be learned</h1>
<h2>Kotlin must be learned</h2>
<h3>Kotlin must be learned</h3>
<h4>Kotlin must be learned</h4>
<h5>Kotlin must be learned</h5>
<h6>Kotlin must be learned</h6>
name attribute value
Methods to extend for companion objects
Properties that extend for companion objects

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.