The `apply` function in Kotlin is a scope function that allows you to configure an object within a block of code and then return the object itself. It’s particularly useful for initializing or configuring an object without having to reference the object’s name multiple times.
### What `apply` is Doing
In your code, `apply` is being used to set the properties `name` and `age` of `Person` objects in a more concise way. Here’s a breakdown of how it works:
1. **Create a new `Person` object**.
2. **Call `apply` on the newly created object**.
3. **Inside the `apply` block, refer to the object using `this` implicitly** (so you don’t need to use the object’s name to set its properties).
4. **Return the object itself after the block is executed**.
### Example Code with Explanation
```kotlin
class Person {
var name: String = ""
var age: Int = 0
fun printInfo() {
println("Name: $name, Age: $age")
}
fun celebrateBirthday() {
this.age += 1
println("Happy Birthday, ${this.name}! You are now ${this.age} years old.")
}
fun greet() {
println("Hello, $name! Welcome to our community!")
}
fun lifeStory() {
println("$name's Life Story: \n$name was born $age years ago. Over the years, $name has experienced many adventures and learned a lot. Now, at the age of $age, $name is excited about the future!")
}
}
fun main() {
val person1 = Person().apply {
name = "Alice"
age = 25
}
val person2 = Person().apply {
name = "Bob"
age = 30
}
person1.printInfo()
person1.celebrateBirthday()
person1.greet()
person1.lifeStory()
person2.printInfo()
person2.celebrateBirthday()
person2.greet()
person2.lifeStory()
}
```
### What Happens in Detail
1. **Creating `person1`**:
```kotlin
val person1 = Person().apply {
name = "Alice"
age = 25
}
```
- A new `Person` object is created.
- `apply` is called on this object.
- Inside the `apply` block, `name` is set to "Alice" and `age` is set to 25.
- The `apply` function returns the `Person` object, now initialized with `name` and `age`.
2. **Creating `person2`**:
```kotlin
val person2 = Person().apply {
name = "Bob"
age = 30
}
```
- Similar steps as above, but for a different `Person` object with `name` set to "Bob" and `age` set to 30.
3. **Calling Methods on `person1` and `person2`**:
- `printInfo()`, `celebrateBirthday()`, `greet()`, and `lifeStory()` methods are called on both `person1` and `person2` to demonstrate their initialized state and behavior.
### Why Use `apply`
- **Readability**: It makes the code more readable by reducing the repetition of the object’s name.
- **Convenience**: It allows you to perform multiple operations on the object in a single block of code.
### Example without `apply`
If you didn’t use `apply`, you would have to write more verbose code:
```kotlin
val person1 = Person()
person1.name = "Alice"
person1.age = 25
val person2 = Person()
person2.name = "Bob"
person2.age = 30
person1.printInfo()
person1.celebrateBirthday()
person1.greet()
person1.lifeStory()
person2.printInfo()
person2.celebrateBirthday()
person2.greet()
person2.lifeStory()
```
Using `apply` simplifies this process, making the initialization and configuration more compact and readable.