Skip to content
Share
Explore

Feb 20 Code Along

Creating an Object:
class Dog(val name: String, var age: Int) // 'name' is immutable, 'age' is mutable

// Main function: entry point of the program
fun main() {
val fifi = Dog("Fifi", 5);
fifi.name = "Julia"

println(fifi)

val peanut = Dog("Peanut", 9) // Create a Dog object with name "Peanut" and age 9
println("age: ${peanut.age} name: ${peanut.name}") // Print age and name using string interpolation
}


megaphone

Here’s a Kotlin code example that uses a loop and a factory method to generate 5 Dog objects and store them in a mutable list. I’ll build on the Dog class from your last example (with a primary constructor), add a factory method to create dogs with varying attributes, and use a loop to populate the list. The code will be ready to copy-paste into IntelliJ IDEA, with comments explaining each part.

Code: Generating 5 Dogs with a Loop and Factory Method

class Dog(val name: String, var age: Int) {

// Method to display dog details (for verification)

fun describe(): String {

return "Dog: $name, Age: $age"

}
// Companion object with a factory method to create dogs

image.png

}

val dogList = mutableListOf<Dog>()

// Main function: entry point of the program
fun main() {
// Use a for loop to generate 5 dogs with the factory method

for (i in 1..5) {

val newDog = Dog.createDog(i) // Call factory method

dogList.add(newDog) // Add to the list

}

for (i in 1..5) {

val newDog = Dog.createDog(i) // Call factory method

dogList.add(newDog) // Add to the list
}
// Print all dogs to verify

println("Generated Dogs:")
dogList.forEach { println(it.describe()) }
}

Explanation of the Code

Dog Class:
Primary Constructor: Dog(val name: String, var age: Int)—kept from your example.
Method describe(): Added to easily print each dog’s details.
Companion Object:
A companion object is Kotlin’s way to define static-like methods tied to the class.
createDog(index: Int) is the factory method, generating a Dog with a name like "Dog1" and an age based on the index (starting at 2 + index).
Factory Method:
fun createDog(index: Int): Dog:
Takes an index parameter to customize each dog.
Names are generated as "Dog1", "Dog2", etc., for uniqueness.
Ages increment from 3 to 7 (2 + index) to show variation.
Returns a new Dog object.
Mutable List:
val dogList = mutableListOf<Dog>() creates an empty list that can hold Dog objects.
mutableListOf() allows adding elements dynamically (unlike listOf(), which is immutable).
Loop:
for (i in 1..5) runs 5 times, creating one dog per iteration.
Calls Dog.createDog(i) to generate each dog and adds it to dogList with add().
Printing:
dogList.forEach { println(it.describe()) } iterates over the list and prints each dog’s description.

Running in IntelliJ

Copy-paste into a new Kotlin file (e.g., DogFactory.kt).
Click the Run icon (green triangle) next to fun main() or press Shift+F10 (Windows/Linux) / Control+R (Mac).
Check the console output to see the 5 dogs.

Why This Approach?

Loop: Automates creating multiple objects efficiently.
Factory Method: Encapsulates object creation logic, making it reusable and flexible (e.g., you could tweak createDog() to randomize ages).
Mutable List: Stores the dogs for later use, aligning with composition concepts (a collection "has-a" set of objects).
Review Tie-In: Uses classes (Lab 5), loops (Lab 2), and prepares for object interactions (Lab 10).

Optional Variations

Random Ages:
kotlin
WrapCopy
fun createDog(index: Int): Dog {
val name = "Dog$index"
val age = (2..10).random() // Random age between 2 and 10
return Dog(name, age)
}
Different Names:
Replace "Dog$index" with a list like listOf("Max", "Luna", "Rex", "Bella", "Rocky") and use names[index - 1].

megaphone

Primary and Secondary Constructors


Here’s a Kotlin code example that demonstrates primary and secondary constructors using a dog-related theme. I’ll extend the Dog class to show how to create Dog objects with different levels of information—using a primary constructor for full details and a secondary constructor for a simpler case.
** Also See Page 48 of the Lab Book

Code: Dogs with Primary and Secondary Constructors


// Dog class with primary and secondary constructors
class Dog(val name: String, var age: Int, var breed: String) {
// Primary constructor: Takes name, age, and breed
// Properties are defined directly with val/var in the constructor

init {
// Validation in init block (runs for all constructors)
if (age < 0) {
age = 0
println("Warning: Age was negative, set to 0 for $name")
}
println("Dog created: $name, $age years old, Breed: $breed")
}


// Secondary constructor: Takes only name, defaults age and breed
constructor(name: String) : this(name, 1, "Unknown") {
println("Secondary constructor used: Default age 1, breed Unknown")
}


// Method to display dog details
fun describe(): String {
return "Dog: $name, Age: $age, Breed: $breed"
}

}


// Main function to demonstrate both constructors
fun main() {
// Using primary constructor with full details
val peanut = Dog("Peanut", 9, "Beagle")
println(peanut.describe())


// Using secondary constructor with just a name
val stray = Dog("Stray")
println(stray.describe())


// Test with invalid age (caught by init block)
val puppy = Dog("Puppy", -2, "Labrador")
println(puppy.describe())

}

Output When Run

Dog created: Peanut, 9 years old, Breed: Beagle
Dog: Peanut, Age: 9, Breed: Beagle

Dog created: Stray, 1 years old, Breed: Unknown

Secondary constructor used: Default age 1, breed Unknown

Dog: Stray, Age: 1, Breed: Unknown

Warning: Age was negative, set to 0 for Puppy

Dog created: Puppy, 0 years old, Breed: Labrador

Dog: Puppy, Age: 0, Breed: Labrador

Explanation of the Code

Primary Constructor:
Definition: class Dog(val name: String, var age: Int, var breed: String)
Takes three parameters: name (immutable), age (mutable), and breed (mutable).
These are directly declared as properties using val and var in the constructor.
Usage: Dog("Peanut", 9, "Beagle") creates a dog with all details specified.
Init Block: Runs after the primary constructor, validating age and printing a creation message.
Secondary Constructor:
Definition: constructor(name: String) : this(name, 1, "Unknown")
Takes only name and defaults age to 1 and breed to "Unknown".
Uses : this() to call the primary constructor with these defaults.
Adds a println to show it’s been used.
Usage: Dog("Stray") creates a dog with minimal info, relying on defaults.
Init Block:
Shared by both constructors—ensures age isn’t negative (sets it to 0 if it is).
Prints a creation message for every Dog object, showing the constructor’s result.
Method describe():
Returns a string with the dog’s details, used to verify the objects in main().
Want to print your doc?
This is not the way.
Try clicking the ··· in the right corner or using a keyboard shortcut (
CtrlP
) instead.