Kotlin Help

Intermediate: Objects

In this chapter, you'll expand your understanding of classes by exploring object declarations. This knowledge will help you efficiently manage behavior across your projects.

Object declarations

In Kotlin, you can use object declarations to declare a class with a single instance. In a sense, you declare the class and create the single instance at the same time. Object declarations are useful when you want to create a class to use as a single reference point for your program or to coordinate behavior across a system.

Objects in Kotlin are lazy, meaning they are created only when accessed. Kotlin also ensures that all objects are created in a thread-safe manner so that you don't have to check this manually.

To create an object declaration, use the object keyword:

object DoAuth {}

Following the name of your object, add any properties or member functions within the object body defined by curly braces {}.

For example, let's say that you wanted to create an object called DoAuth that is responsible for authentication:

object DoAuth { fun takeParams(username: String, password: String) { println("input Auth parameters = $username:$password") } } fun main(){ // The object is created when the takeParams() function is called DoAuth.takeParams("coding_ninja", "N1njaC0ding!") // input Auth parameters = coding_ninja:N1njaC0ding! }

The object has a member function called takeParams that accepts username and password variables as parameters and returns a string to the console. The DoAuth object is only created when the function is called for the first time.

Data objects

To make it easier to print the contents of an object declaration, Kotlin has data objects. Similar to data classes, which you learned about in the beginner tour, data objects automatically come with additional member functions: toString() and equals().

To create a data object, use the same syntax as for object declarations but prefix it with the data keyword:

data object AppConfig {}

For example:

data object AppConfig { var appName: String = "My Application" var version: String = "1.0.0" } fun main() { println(AppConfig) // AppConfig println(AppConfig.appName) // My Application }

For more information about data objects, see Data objects.

Companion objects

In Kotlin, a class can have an object: a companion object. You can only have one companion object per class. A companion object is created only when its class is referenced for the first time.

Any properties or functions declared inside a companion object are shared across all class instances.

To create a companion object within a class, use the same syntax for an object declaration but prefix it with the companion keyword:

companion object Bonger {}

To access any properties or functions of the companion object, reference the class name. For example:

class BigBen { companion object Bonger { fun getBongs(nTimes: Int) { repeat(nTimes) { print("BONG ") } } } } fun main() { // Companion object is created when the class is referenced for the // first time. BigBen.getBongs(12) // BONG BONG BONG BONG BONG BONG BONG BONG BONG BONG BONG BONG }

This example creates a class called BigBen that contains a companion object called Bonger. The companion object has a member function called getBongs() that accepts an integer and prints "BONG" to the console the same number of times as the integer.

In the main() function, the getBongs() function is called by referring to the class name. The companion object is created at this point. The getBongs() function is called with parameter 12.

For more information, see Companion objects.

Practice

Exercise 1

You run a coffee shop and have a system for tracking customer orders. Consider the code below and complete the declaration of the second data object so that the following code in the main() function runs successfully:

interface Order { val orderId: String val customerName: String val orderTotal: Double } data object OrderOne: Order { override val orderId = "001" override val customerName = "Alice" override val orderTotal = 15.50 } data object // Write your code here fun main() { // Print the name of each data object println("Order name: $OrderOne") // Order name: OrderOne println("Order name: $OrderTwo") // Order name: OrderTwo // Check if the orders are identical println("Are the two orders identical? ${OrderOne == OrderTwo}") // Are the two orders identical? false if (OrderOne == OrderTwo) { println("The orders are identical.") } else { println("The orders are unique.") // The orders are unique. } println("Do the orders have the same customer name? ${OrderOne.customerName == OrderTwo.customerName}") // Do the orders have the same customer name? false }
interface Order { val orderId: String val customerName: String val orderTotal: Double } data object OrderOne: Order { override val orderId = "001" override val customerName = "Alice" override val orderTotal = 15.50 } data object OrderTwo: Order { override val orderId = "002" override val customerName = "Bob" override val orderTotal = 12.75 } fun main() { // Print the name of each data object println("Order name: $OrderOne") // Order name: OrderOne println("Order name: $OrderTwo") // Order name: OrderTwo // Check if the orders are identical println("Are the two orders identical? ${OrderOne == OrderTwo}") // Are the two orders identical? false if (OrderOne == OrderTwo) { println("The orders are identical.") } else { println("The orders are unique.") // The orders are unique. } println("Do the orders have the same customer name? ${OrderOne.customerName == OrderTwo.customerName}") // Do the orders have the same customer name? false }

Exercise 2

Create an object declaration that inherits from the Vehicle interface to create a unique vehicle type: FlyingSkateboard. Implement the name property and the move() function in your object so that the following code in the main() function runs successfully:

interface Vehicle { val name: String fun move(): String } object // Write your code here fun main() { println("${FlyingSkateboard.name}: ${FlyingSkateboard.move()}") // Flying Skateboard: Glides through the air with a hover engine println("${FlyingSkateboard.name}: ${FlyingSkateboard.fly()}") // Flying Skateboard: Woooooooo }
interface Vehicle { val name: String fun move(): String } object FlyingSkateboard : Vehicle { override val name = "Flying Skateboard" override fun move() = "Glides through the air with a hover engine" fun fly(): String = "Woooooooo" } fun main() { println("${FlyingSkateboard.name}: ${FlyingSkateboard.move()}") // Flying Skateboard: Glides through the air with a hover engine println("${FlyingSkateboard.name}: ${FlyingSkateboard.fly()}") // Flying Skateboard: Woooooooo }

Exercise 3

You have an app where you want to record temperatures. The class itself stores the information in Celsius, but you want to provide an easy way to create an instance in Fahrenheit as well. Complete the data class so that the following code in the main() function runs successfully:

Hint

Use a companion object.

data class Temperature(val celsius: Double) { val fahrenheit: Double = celsius * 9 / 5 + 32 // Write your code here } fun main() { val fahrenheit = 90.0 val temp = Temperature.fromFahrenheit(fahrenheit) println("${temp.celsius}°C is $fahrenheit °F") // 32.22222222222222°C is 90.0 °F }
data class Temperature(val celsius: Double) { val fahrenheit: Double = celsius * 9 / 5 + 32 companion object { fun fromFahrenheit(fahrenheit: Double): Temperature = Temperature((fahrenheit - 32) * 5 / 9) } } fun main() { val fahrenheit = 90.0 val temp = Temperature.fromFahrenheit(fahrenheit) println("${temp.celsius}°C is $fahrenheit °F") // 32.22222222222222°C is 90.0 °F }

Next step

Intermediate: Open and special classes

Last modified: 01 May 2025