ZOFTINO.COM android and web dev tutorials

Kotlin Classes and Objects Tutorial

In this tutorial you can learn how to define and use classes and its related elements. For learning kotlin basics, see kotlin basics tutorial.

Table of Contents

Defining Class and Primary Constructor

Kotlin class is defined using class keyword followed by class name.

class OrderHandler { }

One of the constructors of kotlin class can be placed after class name, which is called primary constructor.

class OrderHandler (orderId : Int) {}

If you need to use annotations or other modifier for primary constructor, you will have to use constructor key word to define the primary constructor.

class OrderHandler @Inject constructor(orderId : Int) {}

You can declare private constructor using modifier.

class OrderHandler  private constructor(orderId : Int) {}

You can’t add any code to the primary constructor. But you can access the parameters of primary constructor in init blocks which get executed in the order in which they are defined in the class when the class is instantiated.

class OrderHandler(orderId : Int) {
    init {
        println("processing order with order id: ${orderId}")
    }
}

Primary constructor parameters can also be assigned to class properties as shown in the following code.

class OrderHandler(orderId : Int) {
    var orderNumber = orderId
}

If you don’t declare any constructors in a class, default constructor is generated.

Instantiating Class

To create an object of a kotlin class, define a variable using val or var and initialize the variable by calling one of the constructors of the class and passing the required arguments. Here is an example of initializing our OrderHandler class which has the primary constructor.

fun main(args: Array<String>) {
    var orderHand = OrderHandler(233)
}

Output shows that init block gets executed on instantiating the class.

processing order with order id: 233

Secondary Constructors

If a class needs to have more than one constructor, one constructor can be added as primary constructor as explained in the previous section and rest of them can be defined in the class body as secondary constructors or all of them can be defined as secondary constructors in the body of the class.

Here is an example of a class having more than one constructor defined in the body of the class.

class OrderHandler{
    var orderNumber = 1
    var orderAmt : Double = 0.0

    constructor(orderId : Int){
        orderNumber = orderId
    }
    constructor(orderId : Int, orderAmt:Double){
        orderNumber = orderId
        this.orderAmt = orderAmt
    }
}

Here is an example of a class with primary and secondary constructors. Secondary constructor needs to call primary constructor.

class OrderHandler(orderId : Int) {
    var orderNumber = orderId
    var orderAmt : Double = 0.0

    constructor(orderId : Int, orderAmt:Double) : this(orderId){
        println("processing order with order id: $orderId and order amount: $orderAmt")
        this.orderAmt = orderAmt
    }
    init {
        println("init block order id: $orderId")
    }
}

If you instantiate the class using secondary constructor, first init block gets executed then the secondary constructor.

fun main(args: Array<String>) {
    var orderHand = OrderHandler(233, 2000.55)
}

Outout

init block order id: 233
processing order with order id: 233 and order amount: 2000.55

Class Properties

You can add properties to kotlin classes by defining them using var (mutable) or val (constants) keywords.

package com.zoftino.shop

class Order{
    var productId: String = ""
    var productName: String = ""
    var brand: String = ""
    var price: Double = 0.00
    var mrp: Double = 0.00
    var stock: Boolean = true
}

Here is how the properties of a class are used in constructors and functions.

constructor(productId: String){
    this.productId = productId
}

Default Getters and Setters of Properties

To access properties or set values, you can define getter and setter method. By default, get() and set() methods are created. First let’s see how to use default getter and setter methods.

class Order{
    var productId: String = ""
    var productName: String = ""
    var brand: String = ""
    var price: Double = 0.00

    constructor(productId: String, productName: String,
                brand: String, price: Double){
        this.productId = productId
        this.productName = productName
        this.brand = brand
        this.price = price
    }
}

Now let’s instantiate the Order class, access properties by using default getter and assign new value to the properties using default setter. Kotlin creates get() and set() methods for each property. When you access a property by its name, default get is used to return the value of the property. When you assign a new value to a property by referencing the property using the object and property name, default set method is used to assign the new value to the property as shown the following example.

fun main(args: Array<String>) {
    var order = Order("ae23", "Apple iPhone", "Apple", 299.99)

    //default getter
    println("price: "+order.price)
    println("brand: "+order.brand)

    //default setter
    order.productName = "Samsung galaxy"
    order.brand = "Samsung"
    order.price =  199.99

    //default getter
    println("price: "+order.price)
    println("brand: "+order.brand)
}

Output

price: 299.99
brand: Apple
price: 199.99
brand: Samsung

If you need to add any access modifiers like private or any annotation like @Inject to default getters and setters, you can just add them to assessors without body.

var productId: String = ""
public get
@Inject set

Custom Setter and Getter

You can define custom setter and getter for a property in the property definition. Following example shows how to define custom getter and setter for brand property in Order class.

fun main(args: Array<String>) {
    var order = Order("2222", "lg")

    println("brand: "+order.brand)

    order.brand = "Moto"
    println("brand: "+order.brand)
}
class Order{
    var productId: String = ""
    var brand: String
        get() = field.toUpperCase()
        set(value){
            field = value.toLowerCase()
        }

    constructor(productId: String, brand: String){
        this.productId = productId
        this.brand = brand
    }
}

Output

brand: LG
brand: MOTO

In the getter and setter assessors, field identifier is used to refer to the backing field of the property. The back field is automatically created and you must use field as identifier to access it. In the setter, the value refers to the value being assigned to the property, instead of value, you can use your own identifier.

Defining Methods in Class

Methods can be defined in a class using fun keyword, then adding method name, parameters and body as explained in kotlin basics tutorial. Here is an example of defining a method and invoking it.

fun main(args: Array<String>) {
    var orderHand = OrderHandler(2383)
    orderHand.checkOrderQuality(2)
}

class OrderHandler(orderId : Int) {
    var orderNumber = orderId

    fun checkOrderQuality(level: Int){
        if(level == 1){
            println("get order details and then check stock")
        }else{
            println("get order details, stock and shipping time")
        }
    }
}

Inheritance in Kotlin

Inheritance allows a class to have properties and behavior of another class in addition to its own properties and behavior. See inheritance in java tutorial for more information on inheritance and how it works in java.

By default all kotlin classes are sub classes of Any which has just equals, hashCode and toString methods.

In order for a class to be inheritable, open keyword needs to be added to the header of the class definition because by default all classes in kotlin are final meaning they can’t be inherited.

open class Pricer(productId : String) {
    var productId : String
    init{
        this.productId = productId
    }
}

To extend a class, you need to add the class being inherited to the header of the class inheriting it by adding the colon after primary constructor definition, then super class name and constructor parameters.

class BestPricer(productId : String, type: String) : Pricer(productId){
    var type:  String
    init{
        this.type = type
    }
}

If the subclass doesn’t have a primary constructor, it can initialize super class using super key word in the secondary constructors header passing parameters.

class BestPricer : Pricer{
    var type: String = ""

    constructor(productId : String, type: String) : super(productId){        
        this.type = type
    }
}

Overriding Methods

Subclass can override methods of its super class. Like a class by default is final in kotlin, by default, methods are also final. Like open is used to make a class extendable, you need to add open key word to method definition in super class so that the method can be overridden in sub class. For example, bestPrice method can be overridden in subclasses of Pricer because it has open in its header.

open class Pricer(productId : String) {
    private var productId : String = productId

    open fun bestPrice() : Double{
        println("applying rules to get best price")
        return 33333.88
    }

    fun maxDiscountPercentage() : Int{
        println("getting max discount")
        return 10
    }
}

In the subclass, you need to add override to method heard to override a super class method.

class BestPricer : Pricer{
    constructor(productId : String) : super(productId)
    override fun bestPrice() : Double{
        println("applying rules to get best price")
        return 33333.88
    }
}

If open keyword is not added to method header in super class or override is not used in subclass, you will get compiler error.

Defining and Implementing Interfaces

Following is an example of kotlin interface

interface PaymentProcessor {
    fun processPayment(amount: Double, creditAccDetails: String)
}

Following is an example of a class implementing an interface.

class CreditPaymentProcessor :  PaymentProcessor {
    override fun processPayment(amount: Double, creditAccDetails: String) {
        println("processing credit card payment ")
    }
}