Overview:

At this stop on our Kotlin tutorial series journey, we will be learning about Classes there are multiple ways to define a Class. In this tutorial, we cover the definition and instantiation (creating an instance) of a standard Kotlin Class. In later tutorials, we will cover Data Classes and Objects.

Defining classes allows us to encapsulate our logic beyond the main.kt file; earlier we discussed how to define methods. Classes allow us to model our applications in real-world terms and allow us to restrict the scope of the application and group our functions that are related to a thing; this provides application security as well as readability.

Requirements:

Source Code:

https://github.com/codetober/kotlin-classes

Defining a Class

Defining your first class is really easy! In examples of this tutorial, we will be refactoring the MoonBucks cafe that we started in the Kotlin Functions tutorial, you can find the source for that project on Github if you’re coding along. Although it’s not a requirement, we will be creating classes in separate files unless there is a good reason to do otherwise.

To define a class is very easy, however, a class is not very useful until its main parts have been added.

The main parts of a class are the:

  • Properties
  • Functions
  • Constructors
class Store {
    // Constructors

    // Properties

    // Functions
}

Class Properties and Functions

Class properties and functions are the same as the variables and functions we’ve defined in previous tutorials; the main difference is that we can modify the property visibility and customize the class’s behavior. Let’s add some properties and functions to our Store.kt class.

class Store {
    // Constructors

    // Properties
    private val menu = Menu()

    // Functions
    public fun printWelcomeMessage() = ""
    public fun printExitMessage() = ""
    public fun placeOrder() = ""

    private fun calculateOrderPrice() = ""
}

Notice that we are using private and public visibility modifiers on the properties and functions. By changing the visibility of the fields and functions we are able to control how our new class is used and which fields are accessible to other parts of our application. It’s a good practice to keep classes as restricted as possible when creating them; this helps to prevent abuse of the class. The following keywords are examples of the modifiers that we can use to affect our class properties and functions.

  • Public – Property or Function is visible outside of this class. By default, if you omit the visibility modifier, Kotlin will assign properties and functions to be public.
  • Private – Visibility is limited to this class only.
  • Protected – Properties and Functions defined will be available in this class as well as any subclasses (if the class is defined as open).
  • Internal – These Properties and Functions will only be accessible in its module.

Class Constructors

So far, we have not defined a constructor and that is okay! There are two types of constructors: primary and secondary. When we chose not to define a constructor in our code snippet above, Kotlin added an empty primary constructor automatically. However, if we choose to implement our own primary constructor we can do that as well, as see below.

class Store(val name: String = "MoonBucks"){
    // ...
}

Secondary constructors are defined with slightly different syntax. If a secondary constructor is used, it is required to call the primary constructor and provide values for all of the primary (super) constructor arguments. You may choose to define a secondary constructor if the primary is too verbose or if you would like to further customize the instance of the class you’ve created.

Class Initializer Block

In addition to the primary and secondary constructors, classes have an optional block of code that can be executed when either of the constructors are invoked; the Initializer Block. Using init we can define more variables or we can perform validation on constructor values. In this example, we are checking if our new Store instance has a name with more than one character.

class Store(val name: String = "MoonBucks"){

    init{
        require(name.length > 1) {"Store Name must contain more than one character!"}
    }

    // ...
}

Next, we will look at how to create an instance of our Store class.

Instantiating a Kotlin Class

In order to use our newly defined class, we must create an instance of the class. Because we added a default value for the name argument in the primary constructor of Store we are not required to provide any parameters when creating a new Store instance. However, if we want to create a Store with a name other than “MoonBucks” we could simply provide the name argument to the primary constructor – but, why would we want to do that?!

fun main(args: <String>) {
    val moonBucks = Store()
    // (optional) val asteroidCafe = Store("Asteroids")

    println(moonBucks.name)
}

Now, the remaining task is to take the knowledge from this tutorial and continue to refactor the MoonBucks cafe. To do this, you should create a class for a Customer. In a later tutorial when we cover Data Classes and Objects, we will define a Menu as well as MenuItems.

View the source code for this tutorial to see the full syntax for class definitions and our representation of the User class.

 

That’s it! Congratulations on making it all the way through this tutorial and continuing your quest to craft amazing code! If you liked this tutorial, please share it 🙂 Comment below with any questions or issues you faced.