Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why to put val or var in kotlin class constructors

Just learning Kotlin In the first code down below there is the val keyword right in the other code there is not, what is the different here if the val and var is omitted?

class Person(val firstName: String, val lastName: String) {
}

class Person(firstName: String, lastName: String) {
}
like image 489
Tord Larsen Avatar asked Sep 29 '18 09:09

Tord Larsen


People also ask

What is the difference between VAR and Val in Kotlin?

var is like a general variable and can be assigned multiple times and is known as the mutable variable in Kotlin. Whereas val is a constant variable and can not be assigned multiple times and can be Initialized only single time and is known as the immutable variable in Kotlin.

Why do we need constructor in Kotlin?

A Kotlin constructor is a special member function in a class that is invoked when an object is instantiated. Whenever an object is created, the defined constructor is called automatically which is used to initialize the properties of the class.

Why does Kotlin need a secondary constructor?

Secondary Constructor A class in Kotlin can have at most one primary constructor, and one or more secondary constructors. The primary constructor initializes the class, while the secondary constructor is used to initialize the class and introduce some extra logic.


2 Answers

If val or var is omitted then they won't be properties, but parameters passed to constructor. You won't be able to work with them outside of constructor.

like image 197
Mike Avatar answered Oct 08 '22 19:10

Mike


If you omit val or var in in a constructor, then the only places that can access these parameters are initialization statements that are evaluated at construction time. See https://kotlinlang.org/docs/reference/classes.html

This is useful when you want to do something with a value before storing it. In Java you would put that code a constructor body

class Person(firstName: String, lastName: String) {
    // directly in val / var declarations
    val firstName = firstName.capitalize()
    val lastName = lastName

    // in init blocks
    val fullName: String
    init {
        fullName = "$firstName $lastName"
    }

    // secondary constructors can only see their own parameters
    // and nothing else can access those
    constructor(fullName: String) : this("", fullName)
}

But it also works for delegation using by

interface Named {
    fun getName(): String
}
class Human(private val fname: String, private val lname: String) : Named {
    override fun getName() = "$fname + $lname" // functions need val since
                                               // value is resolved after construction
}
class Person2(firstName: String, lastName: String) : Named by Human(firstName, lastName)

class Person3(human: Human) : Named by human {
    constructor(firstName: String, lastName: String): this(Human(firstName, lastName))
}

Or in property delegation

class Person4(firstName: String, lastName: String) {
    val fullName: String by lazy { "$firstName $lastName" }
}

Note: the closure is captured at initialization time, the values are therefore still available when lazy evaluates eventually.

like image 42
zapl Avatar answered Oct 08 '22 17:10

zapl