cluster1
cluster1

Reputation: 5664

Kotlin getter / setter when using a primary constructor

The example is from a Kotlin-course I'm doing:

class Car {
    var speed: Int = 0
        get() = field 
        set(value) {
            field = value
        }
}

If I like to use a primary constructor like this:

class Car(var speed: Int)

How would I have to write the getter / setter in that case?

Upvotes: 35

Views: 26090

Answers (4)

tronman
tronman

Reputation: 10115

Although Animesh Sahu's answer is technically correct, getters and setters should not have explicit getters and setters if the only thing the getter and setter is doing is getting and setting a backing field as shown in the poster's example.

A more likely scenario is using a setter to restrict a property's values. For example, you may want to prevent speed from being negative:

class Car(speed: Int) {
    var speed = speed
        get() = field 
        set(value) {
            if (value >= 0) {
               field = value
            }
        }
}

However, you might be surprised to learn that a Car can be created with a negative speed:

val someCar = Car(-2)
println(someCar.speed)   // Prints -2

This is because the setter is not called when initializing the speed property. You must add an initializer block to call the setter with the constructor value:

class Car(speed: Int) {
    var speed = 0
        get() = field 
        set(value) {
            if (value > 0) {
               field = value
            }
        }

   init {
      // Call setter
      this.speed = speed
   }
}

Now when a Car is created with a negative speed, the setter ignores it, and the speed remains the default value of 0:

val someCar = Car(-2)
println(someCar.speed)   // Prints 0

Upvotes: 0

Krishna Sony
Krishna Sony

Reputation: 1369

Syntax of property –

var <propertyName>[: <PropertyType>] [= <property_initializer>]
    [<getter>]
    [<setter>]

Here, property initializer, getter and setter are optional. We can also omit property type if it can be inferred from the initializer. The syntax of a read-only or immutable property declaration differs from a mutable one in two ways: starts with val instead of var, and does not allow a setter.

In kotlin, val is used as only for read means getter and var is used as for not getter() and setter()

class Company {
var name: String = "Defaultvalue"
}

The above code is equivalent to the below code

class Company {
    var name: String = "defaultvalue"
        get() = field                     // getter
        set(value) { field = value }      // setter
}

You can also use kotlin data class if you want to hold data in your Car class. so you no need to define getter and setter.

data class Car(var speed: Int)

For more check https://kotlinlang.org/docs/reference/properties.html#getters-and-setters

Upvotes: 1

Animesh Sahu
Animesh Sahu

Reputation: 8096

You cannot write getters/setters inside of the constructor, you can do the following:

  1. Create variable inside class whose value taken from constructor.
class Car(speed: Int) {
    var speed = speed
        get() = field 
        set(value) {
            field = value
        }
}
  1. Use @JvmField annotation to restrict compiler not to auto-generate getters/setters and implement one yourself
class Car(@JvmField private var speed: Int) {
    fun getSpeed() = speed
    fun setSpeed(value: Int) { speed = value }
}

Upvotes: 51

Andrei Tanana
Andrei Tanana

Reputation: 8422

You can just initialize your property with the value from constructor:

class Car(speed: Int) {
    var speed: Int = speed
        get() = field
        set(value) {
            field = value
        }
}

Upvotes: 8

Related Questions