Android Development with Kotlin
Kotlin Basics
Your First Kotlin Program
Let's start with a tradition in the programming world: getting the computer to say "Hello, World!". In Kotlin, it's remarkably simple. Every Kotlin application needs an entry point, a starting line for the computer to begin executing code. This is called the main function.
fun main() {
println("Hello, World!")
}
That's it. The fun keyword is how you declare a function in Kotlin. main is the special name for the function that starts the program. Inside the curly braces { } is the code that runs. Here, println() is a built-in function that prints a line of text to the console.
Storing Information
To do anything useful, programs need to work with data. We store this data in variables. Think of a variable as a labeled box where you can keep a piece of information. Kotlin has two main types of boxes: val and var.
Use
valfor a value that never changes (immutable). Usevarfor a value that can change (mutable).
It's a good practice to prefer val whenever possible. This makes your code safer and easier to understand because you know the value won't be changed accidentally somewhere else in the program. You only use var when you specifically need to reassign a variable later on, like for a counter.
// Using val (value) - cannot be changed
val name = "Alex"
val yearOfBirth = 1995
// Using var (variable) - can be changed
var score = 0
score = 10 // This is okay
// name = "Bob" // This would cause an error!
Notice we didn't have to explicitly state the type of data we were storing. Kotlin is smart enough to figure it out on its own. It sees "Alex" and knows it's a String (text). It sees 1995 and knows it's an Int (integer). This is called type inference. Of course, you can be explicit if you want to be.
val language: String = "Kotlin"
val version: Double = 1.9
Making Decisions and Repeating Actions
Programs often need to make decisions. The most common way to do this is with an if-else statement. It's just like it sounds: if a certain condition is true, do one thing, else do something different.
val temperature = 25
if (temperature > 20) {
println("It's a warm day!")
} else {
println("It might be a bit chilly.")
}
For more complex choices, Kotlin provides a clean and powerful tool called when. It's like a more flexible version of the switch statement found in other languages. You can use it to check a variable against many possible values.
val dayOfWeek = 5
val dayName = when (dayOfWeek) {
1 -> "Sunday"
2 -> "Monday"
3 -> "Tuesday"
4 -> "Wednesday"
5 -> "Thursday"
6 -> "Friday"
7 -> "Saturday"
else -> "Invalid day"
}
println("Today is $dayName.") // Prints: Today is Thursday.
Sometimes you need to repeat an action multiple times. This is where loops come in. The for loop is perfect for running a block of code a specific number of times or for going through each item in a collection.
// Prints numbers 1 through 5
for (i in 1..5) {
println(i)
}
A while loop is used when you want to repeat an action as long as a certain condition remains true. You might not know exactly how many times it will run beforehand.
var countdown = 3
while (countdown > 0) {
println(countdown)
countdown-- // Decrement the counter
}
println("Liftoff!")
Reusable Blocks of Code
As programs grow, you'll find yourself wanting to reuse pieces of code. That's what functions are for. We already saw the main function. You can create your own functions to perform specific tasks. This helps organize your code and avoid repetition.
A function is a named block of code that performs a specific task. It can take inputs (parameters) and produce an output (a return value).
Let's create a function that greets a person by name. It takes one parameter, name, which is a String. It doesn't return any value, so its work is done after it prints the message.
fun greet(name: String) {
println("Hello, $name!")
}
// Now we can call the function
greet("Maria") // Prints: Hello, Maria!
greet("David") // Prints: Hello, David!
Functions can also calculate something and give back a result. Here’s a function that adds two numbers and returns the sum. We specify the type of the return value after the parentheses.
fun add(a: Int, b: Int): Int {
return a + b
}
val sum = add(5, 3)
println(sum) // Prints: 8
For very simple functions, Kotlin offers a more concise syntax.
fun multiply(a: Int, b: Int) = a * b
Kotlin also has a powerful feature called lambdas, which are essentially functions without a name. They are chunks of code you can pass around as variables. We won't dive deep into them now, but it's good to know they exist as they are used frequently in Android development.
Organizing Code with Classes
Object-oriented programming (OOP) is a way of thinking about and structuring code. The central idea is to bundle data and the functions that operate on that data into a single unit called an object. A class is the blueprint for creating these objects.
class
noun
A blueprint for creating objects. It defines a set of properties (data) and methods (functions) that the created objects will have.
Let's create a simple Dog class. Our dog will have a name and an age, and it will know how to bark.
class Dog(val name: String, var age: Int) {
fun bark() {
println("Woof!")
}
}
Now that we have the blueprint, we can create actual Dog objects from it. This is called creating an instance of the class.
// Create two instances of the Dog class
val myDog = Dog("Fido", 3)
val neighborsDog = Dog("Lucy", 5)
// Access their properties
println(myDog.name) // Prints: Fido
// Call their methods
neighborsDog.bark() // Prints: Woof!
What if we want to model different kinds of animals? This is where inheritance comes in. We can create a general Animal class with common properties, and then have more specific classes like Dog and Cat inherit from it. The open keyword means that other classes are allowed to inherit from this class.
open class Animal(val name: String) {
fun eat() {
println("$name is eating.")
}
}
// Dog inherits from Animal
class Dog(name: String, var age: Int) : Animal(name) {
fun bark() {
println("Woof!")
}
}
Now, our Dog class automatically gets the name property and the eat function from the Animal class, without us having to write them again.
val fido = Dog("Fido", 3)
fido.eat() // This works! Prints: Fido is eating.
fido.bark()
Finally, an interface is like a contract. It defines a set of functions that a class must implement, but it doesn't provide the actual code for them. This is useful for defining a common behavior that different classes can share.
interface Pet {
fun cuddle()
}
// Dog now implements the Pet interface
class Dog(name: String, var age: Int) : Animal(name), Pet {
fun bark() {
println("Woof!")
}
// We must provide the code for the cuddle function
override fun cuddle() {
println("$name wants to cuddle!")
}
}
Now you have a solid grasp of the building blocks of Kotlin. These fundamentals are the foundation upon which all Android applications are built.