Kotlin constructors: primary and secondary

Viewed 836

Just have started with Kotlin, where you can have a primary constructor and secondary ones. The question may sound simple, but I couldn't find an answer to it (I've read the "constructors" section in the documentation ) - why?

Basically, I'm trying to understand what is the idea behind being primary and secondary. And what is the difference in how they are used (seems like there's not, so why the separation)?

3 Answers

Primary constructor

  • A Kotlin class can only have one primary constructor.
  • Primary constructor provide a simple way to initialize the member properties of a class.
  • It takes a list of comma-separated parameters and declared just after the class name as a part of the header.
// How to declare a primary constructor
class Student constructor(
     firstName:String,
     lastName:String
){
}

// We can omit constructor keyword if the primary constructor 
//does not have any annotations or visibility modifiers

class Student(
     firstName:String,
     lastName:String
){
}

fun main(){
     val student1 = Student("Helen", "trump")
}
  • Since primary constructor in Kotlin has a constrained syntax, it is defined only to declare class properties, it doesn't accept any logic or code. So, to fill this gap Kotlin provides a flexible concept of init block in which we can add more custom code to perform some logic!
class Student(
    firstName:String,
    lastName:String
){
   init{
       println("Welcome to the student profile")
   }
}
  • These initializer block is executed after the primary constructor is called and before any secondary constructors.

Secondary constructor

  • A Kotlin class can have one or more and one or more secondary constructors.
  • They must be prefixed by the keyword constructor.
  • We can't declare class properties inside secondary constructor the same way we do in primary constructor.
  • Every secondary constructor must call explicitly the primary constructor. We can do that by using this keyword.
class Pizza constructor (
    var crustSize: String,
    var crustType: String,
    val toppings: MutableList<String> = mutableListOf()
) {

    // secondary constructor (no-args)
    constructor() : this("SMALL", "THIN")

    // secondary constructor (2-args)
    constructor(crustSize: String, crustType: String) : this(crustSize, crustType, mutableListOf<String>())

    override fun toString(): String = "size: ${crustSize}, type: ${crustType}, toppings: ${toppings}"

}
fun main(args: Array<String>) {
    val p1 = Pizza()
    val p2 = Pizza("LARGE", "THICK")
    val p3 = Pizza("MEDIUM", "REGULAR", mutableListOf("CHEESE", "PEPPERONI"))

    println(p1)
    println(p2)
    println(p3)
}

// output
size: SMALL, type: THIN, toppings: []
size: LARGE, type: THICK, toppings: []
size: MEDIUM, type: REGULAR, toppings: [CHEESE, PEPPERONI]

Reference

Related