Kotlin differs quite a bit from Java in how classes are defined. Writing classes in Java involves so much boilerplate code. To alleviate the pain of typing all that, programmers rely a lot on IDEs to generate code. Good news, you don’t need to type as much. Bad news, you’ll have to wade through all that code each day. Kotlin moves the code generation from the IDE to the compiler—kudos for that, especially for a language created by the company that makes the best IDEs in the world.

The syntax for creating a class in Kotlin is closer to the facilities in Scala than in Java. The number of options and flexibilities seem almost endless; let’s start small and grow the code for creating a class incrementally.

The smallest class

Here’s the minimum syntax for a class—the class keyword followed by the name of the class:

// empty.kts
class Car

We didn’t provide any properties, state, or behavior for this class, so it’s only fair that it does nothing useful.

Read-only properties

Let’s define a property in the class:

// property.kts
class Car(val yearOfMake: Int)

We made a few design decisions right there in that highly concise syntax. We wrote a constructor to take an integer parameter and initialize a read-only property named yearOfMake of type Int—yep, all that in one line. The Kotlin compiler wrote a constructor, defined a field, and added a getter to retrieve the value of that field.

Let’s take a closer look at the class definition. That line is a shortcut for this:

public class Car public constructor(public val yearOfMake: Int)

By default, the access to the class and its members is public and the constructor is public as well. In Kotlin, the line that defines the class is actually defining the primary constructor. The keyword constructor isn’t needed unless we want to change the access modifier or place an annotation for the primary constructor.

Creating instances

Let’s use the class to create an instance. New in Kotlin, related to creating objects, is there’s no new keyword. To create an object use the class name like it’s a function:

// property.kts
val car = Car(2019) 
println(car.yearOfMake) //2019

The immutable variable car holds a reference to a Car instance created by calling the constructor with the value 2019. The property yearOfMake is accessible directly on the instance car. Efforts to modify it will run into issues, like so:

car.yearOfMake = 2019 //ERROR: val cannot be reassigned

Much like val local variables, val properties are immutable too.

Read-write properties

You can design a property to be mutable if you like:

Get hands-on with 1200+ tech skills courses.