Introduction
Ever since Apple released the Swift programming language for iOS, lots of Android developers have wanted a similar language for Android development. If you are one of those developers, you are going to love Kotlin, a JVM language that is remarkably similar to Swift.
Kotlin is a statically-typed language, developed by JetBrains, whose syntax is more expressive and concise than that of Java. With features like higher-order functions, lambda expressions, operator overloading, string templates, and more, Kotlin has a lot more to offer than Java. Because Java and Kotlin are highly interoperable, they can be used together in the same project.
If you are a competent programmer in Java, you will be able to learn Kotlin in a very short time. In this tutorial I will be showing you how to use Kotlin’s most frequently used constructs.
Prerequisites
To follow along with me, you will need:
- a good understanding of Java.
- the latest version of the Kotlin compiler. Alternatively, you could use the online playground.
1. Classes
To create a class in Kotlin, you have to use the class
keyword. For example, here’s how you create an empty class called Person:
class Person { }
Adding Properties
A class usually has properties and member functions (also called methods). Let’s add two properties to the Person
class, name of type String
and age of type Int
.
var name: String = "" var age: Int = 0
As you can see, the syntax for creating variables is slightly different from that of Java. To create a variable in Kotlin, you must use the var
keyword. However, if you want your variable to be a read-only/assign-once variable, use the val
keyword instead.
For the sake of null safety, Kotlin also makes a distinction between variables that can be null
and variables that can never be null
. In our previous example, both the variables name
and age
can never be null
. If they are null, the compiler will raise an error.
To create a variable that can hold null
, you need to add a ?
after the variable’s type. For example:
var college: String? = null
Now that we have a class, creating an instance of it is easy:
var jake = Person()
No, Kotlin doesn’t have the new
keyword. Once the instance has been created, you can access its properties the same way you would in Java:
jake.name = "Jake Hill" jake.age = 24 jake.college = "Stephen's College"
Using Constructors
Initializing the individual properties of our instance the way we just did is not a good coding practice. A better way to do this would be by using a constructor. Kotlin’s syntax to create such a constructor is very compact:
class Person(var name: String, var age: Int, var college: String?) { }
In fact, if you have nothing else to add to your class, you don’t need the curly braces. The following code works just fine:
class Person(var name: String, var age: Int, var college: String?) var jake = Person("Jake Hill", 24, "Stephen's College")
It might already be obvious to you that there’s no way you can add custom code to this constructor. This constructor, which is part of the class’s header, is called the primary constructor.
To add more constructors to your class, known as secondary constructors, you should use the constructor
keyword. Secondary constructors should delegate to the primary constructor using the this
keyword. Let’s add a secondary constructor to our class that initializes the value of a property named email:
class Person(var name: String, var age: Int, var college: String?) { var email: String = "" constructor(name:String, age:Int, college: String?, email: String) : this(name, age, college) { this.email = email } }
To create an instance using the secondary constructor, you write something like this:
var jake = Person("Jake Hill", 24, "Stephen's College", "[email protected]")
Adding Member Functions
In Kotlin, functions are created using the fun
keyword. Let’s add a simple member function named isEligibleToVote that returns a Boolean
value:
fun isEligibleToVote(): Boolean { // If age is greater or equal to 18 // return true return age >= 18 }
Note that the return value’s type is indicated at the end of the function header. You can call this method the same way you would in Java:
jake.isEligibleToVote()
Creating Extensions
Kotlin lets you extend a class by adding additional functions to it without modifying its original definition. Such functions are known as extensions. The names of these functions should be preceded by the names of the classes they extend.
For example, to add an extension called isTeenager to the Person
class, you write the following code outside the class:
fun Person.isTeenager(): Boolean { // If age falls in the range // 13-19 return true return age in 13..19 }
This feature is especially useful when you want to extend classes that do not belong to your project’s code base. For example, the following code snippet adds an extension containsSpaces to the String
class:
fun String.containsSpaces(): Boolean { return this.indexOf(" ")!=-1 }
Creating Derived Classes
It’s important to keep the following in mind when creating a derived class:
- You must use a
:
instead of Java’sextends
keyword. - The header of the base class should have the
open
annotation. - If your base class has a constructor that takes parameters, your derived class should initialize those parameters in the header itself.
Let’s create a class named Employee that derives from Person
:
open class Person(var name: String, var age: Int, var college: String?) { ... } class Employee(name: String, age: Int, college: String?, var company: String) : Person(name, age, college) { }
Overriding Member Functions
In Kotlin, you have to explicitly state that a member function can be overridden by using the open
annotation in the method’s header in the base class. In the derived class, open functions can be overriden using the override
annotation.
For example, to override the isEligibleToVote
method, you add the following code snippet to the Employee
class:
override fun isEligibleToVote(): Boolean { // Always return true return true }
Creating Static Methods
Kotlin does not allow you to create static methods. However, it does allow you to create package level functions that do not belong to any class.
The main
method is perhaps the best known static method. If you want to add the main
method to a package named com.tutsplus.code.tutorial, then your code would look like this:
package com.tutsplus.code.tutorial fun main(args:Array<String>) { }
2. Functions
You’ve already learned how to create simple functions in the previous examples. The syntax you used to create those functions was very similar to that of Java. Kotlin, however, lets you to do a lot more with functions.
Creating Single Expression Functions
If a function returns the value of a single expression, then you can use the =
operator after the function header followed by the expression to define the function.
For example, to add a method to the Person
class that returns true
if the person is an octogenarian, you would write:
fun isOctogenarian(): Boolean = age in 80 .. 89
As you can see, this shorthand syntax is more compact and readable.
Higher Order Functions and Lambda Expressions
Higher order functions are functions that can return functions or accept functions as parameters. A lambda expression, on the other hand, is just a function that has no name. Usually, lambda expressions and higher order functions are used together.
Consider the following example that demonstrates the syntax of a lambda expression:
{x, y -> x+y}
This is a simple lambda expression that takes two parameters, x
and y
, and returns their sum. As you might have guessed, the parameters of the function are listed before the ->
operator and the body of the function starts after the ->
operator. This lambda expression can be assigned to a variable and used as follows:
val sumLambda: (Int, Int) -> Int = {x,y -> x+y} val actualSum = sumLambda(3,4)
Note that the type of the variable that holds the lambda expression specifies the types of its parameters and its return value.
Creating a higher order function that can accept the above lambda expression as a parameter is just as easy. For example, to create a function that doubles the result of the lambda expression, you would write:
fun doubleTheResult(x:Int, y:Int, f:(Int, Int)->Int): Int { return f(x,y) * 2 }
You can call this function as follows:
val result1 = doubleTheResult(3, 4, sumLambda)
Alternatively, you can pass the lambda expression directly to the higher order function:
val result2 = doubleTheResult(3, 4, {x,y -> x+y})
Lambda expressions are often used with arrays. For example, consider the following array of Int
values:
val numbers:Array<Int> = arrayOf(1, 2, 3, 4, 5)
If you want to square the value of each item in the array, you can use the map
function along with a lambda expression as follows:
val squaredNumbers = numbers.map({x -> x * x}) // Result will be a new array that contains // 1, 4, 9, 16, 25
3. Ranges
Range expressions are used very frequently in Kotlin. You already used them while creating the isTeenager
and isOctogenarian
methods.
To create a range, all you need is the ..
operator.
val r1 = 1..5 // This range contains the number 1, 2, 3, 4, 5
To create a range in descending order, use the downTo
function instead.
val r2 = 5 downTo 1 // This range contains the number 5, 4, 3, 2, 1
If you don’t want the step to be 1, you can specify a custom value using the step
function.
val r3 = 5 downTo 1 step 2 // This range contains the number 5, 3, 1
You will see more range expressions later in this tutorial.
4. Conditional Constructs
if
In Kotlin, if
is an expression that returns different values depending on whether the condition has been satisfied. The following example illustrates how this works.
var age = 20 val isEligibleToVote = if(age > 18) "Yes" else "No" // isEligibleToVote will now be set to "Yes"
when
The when
expression is equivalent to Java’s switch
. However, it is a lot more versatile. For instance, consider the following example.
val age = 17 val typeOfPerson = when(age){ 0 -> "New born" in 1..12 -> "Child" in 13..19 -> "Teenager" else -> "Adult" } // typeOfPerson will now be set to "Teenager"
As you can see, when
can not only take single values but also expressions as its conditions.
5. Looping Constructs
for..in
In Kotlin, you can use the for..in
loop to loop through arrays, collections, and anything else that provides an iterator. Its syntax is almost identical to that of Java, except for the use of the in
operator instead of Java’s :
operator. The following example shows you how to loop through an array of String
objects.
val names = arrayOf("Jake", "Jill", "Ashley", "Bill") for (name in names) { println(name) }
With the help of range expressions, you can make this loop behave like a traditional, C-style, for
loop.
for (i in 0..9) { println(i) } // Behaves exactly like // for(int i=0;i<10;i++)
while
and do..while
The syntax of while
and do..while
loops in Kotlin is identical to the syntax used in Java. For example, the following Kotlin code loops over an array of String
objects using a while
loop:
val names = arrayOf("Jake", "Jill", "Ashley", "Bill") var i = names.size() while(i>0) { println(names[--i]) }
6. String Templates
Kotlin lets you embed variables and expressions in strings by wrapping them in a pair of curly braces, prefixed by a $
symbol. For example:
val name = "Bob" println("My name is ${name}") // Prints "My name is Bob" val a = 10 val b = 20 println("The sum is ${a+b}") // Prints "The sum is 30"
Conclusion
In this tutorial, you learned the basics of the Kotlin programming language. Even though we covered several constructs here, Kotlin has a lot more to offer. In fact, as of June 2015, Kotlin is still available only as a preview. It is likely to see several improvements and new features in the coming months.
If you want to know how to use Kotlin in Android Studio, then take a look at How to Use Kotlin in Your Android Projects . To learn more about the Kotlin language, I recommend visiting the Kotlin documentation.
Comments