What a field is
An empty Dog class makes every dog identical. To give each object its own data you attach fields to the class: variables that belong to it. Every object created from the class gets its own copy of each one, so two dogs can have different names without interfering with each other.
In Kotlin a field declared in a class is a property. The compiler also generates a getter, and for var a setter, that outside code uses when it reads or writes the property with a dot.
Declaring properties
class Dog {
var name: String = ""
var age: Int = 0
}
vardeclares a property that can be reassigned.valdeclares one that is assigned once and then read-only.- The type follows the name after a colon:
name: String. - Properties are visible to any code by default.
publicis the default and is normally left out. A later lesson coversprivate.
Every property needs a starting value
Here Kotlin differs from languages that fill in zeros and nulls for you. A property in a class body must be initialized when it is declared, or in the constructor. This does not compile:
class Dog {
var age: Int
}
The compiler reports property must be initialized or be abstract. So there is no automatic 0 for numbers, false for booleans or null for references. If you want a missing value, say so in the type:
class Dog {
var name: String = ""
var age: Int = 0
var nickname: String? = null
}
The ? makes nickname nullable, so null is allowed. A plain String can never be null. For a property that you will assign later but cannot initialize now, lateinit var owner: String skips the initial value. Reading it before assigning throws an UninitializedPropertyAccessException with the message lateinit property owner has not been initialized.
That is why the lesson's step gives each property a default value. It lets Dog() build a dog with no arguments.
Reading and writing
The dot operator reaches a property of one particular object:
val dog = Dog()
dog.name = "Rex"
dog.age = 4
println(dog.name)
The last line prints Rex. Writing dog.age += 1 changes only this dog's age. If you create a second Dog, its name is still "" and its age still 0.
A val property can be read but not assigned. With val species: String = "dog" in the class, d.species = "cat" fails with 'val' cannot be reassigned. Note that val dog = Dog() in the example above is a val variable holding a reference; it is the properties, which are var, that change.
Computed properties
A property does not have to store a value. It can have a getter that computes one each time it is read:
class Dog {
var name: String = ""
var age: Int = 0
val isPuppy: Boolean
get() = age < 2
}
Here isPuppy has no storage of its own. With age set to 1 it reads as true, and after age is set to 5 it reads as false. From the outside it looks like any other property, which is why Kotlin code rarely needs separate getter methods.
The exercise
The starter code has an empty Dog and a mainFunction that prints ${dog.name} is ${dog.age} years old. The ${...} parts are string templates that insert values into the text. The code does not compile because Dog has no name or age. Step 1 declares both properties with var and a default value. Step 2 sets them through the dot operator before the print:
class Dog {
var name: String = ""
var age: Int = 0
}
class Solution {
fun mainFunction() {
val dog = Dog()
dog.name = "Rex"
dog.age = 4
println("${dog.name} is ${dog.age} years old")
}
}
The output is Rex is 4 years old.
Common mistakes
- Omitting the initial value.
var name: Stringin a class body does not compile. - Using
valand then assigning. Avalproperty cannot be changed frommainFunction. - Mismatched types.
dog.name = 5is rejected because aStringproperty cannot hold anInt. - Misspelled property names.
dog.nme = "Rex"fails withunresolved reference 'nme'. - Setting the property on the class. Properties belong to objects, so write
dog.name, notDog.name.
Key takeaways
- A field is a property: a variable declared in a class, with its own copy in every object.
- Use
varwhen the value can change andvalwhen it cannot. - Kotlin gives no automatic defaults: initialize every property, make it nullable, or use
lateinit. - Read and write properties with the dot operator.