khusrav
khusrav

Reputation: 5307

Kotlin constructors: primary and secondary

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)?

Upvotes: 5

Views: 1994

Answers (3)

ujjwal_bansal
ujjwal_bansal

Reputation: 365

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 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 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 explicitly call 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

Upvotes: 4

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272467

The are various syntactic differences, clearly. But a major conceptual difference is that all secondary constructors ultimately delegate to the primary constructor.

The way I think about this is that the primary constructor is the canonical interface for creating an object, and secondary constructors are like static helpers for transforming other argument sets to comply with this interface.*


* Please note this is a personal interpretation, not backed up with official docs in any way!

Upvotes: 8

holi-java
holi-java

Reputation: 30676

the kotlin primary constructor help you to write the compact code :

  • you can write class without body, e.g:data class, for example:

    data class Data(val value:String)
    
  • if you don't have any annotation on constructor, then the keyword constructor can be ommitted. a negative example:

    class Foo @Annotation constructor()
    
  • it make the inherit simply, for example:

    open class Bar(val value: String);
    
    class Primary(value: String, other: String) : Bar(value)
    
    class Secondary : Bar {
        constructor(value: String, other: String) : super(value)
    }
    
  • it can using delegations by keyword by, but secondary constructor can't uses.

    interface Rule {
        fun apply(value: String): Int
    }
    
    
    open class Policy(rule: Rule) : Rule by rule;
    

Upvotes: 0

Related Questions