1.3 Kotlin Overview
If you've never programmed in Kotlin before, you might feel intimidated. Don't worry, it's a fairly intuitive language that simplifies the coding experience while providing powerful tools that ease the development of complex tasks. We'll provide a quick rundown of how it operates, but if you'd like something more in-depth, the Kotlin team has built a great tutorial at https://play.kotlinlang.org/koans/overview.
Variables
Kotlin is a statically-typed language, meaning that the type of the variable is set when being initialized. However, unlike the versions of Java you were most likely taught, Kotlin prefers to infer the type for you. For example, when initializing a variable named x
to the integer value of 3, you can simply declare var x = 3
.
Kotlin has now inferred that variable to be of type int
, and as long as this variable is in the scope of the program, the type of x cannot be changed. Setting x = "hello"
will lead to a compiler error. However, there are cases when Kotlin does not have enough information to infer the variable type. You can explicitly set the type with var x : String = "hello"
Java may have gotten you into the habit of primitives and objects. You can ignore such details when using Kotlin. It doesn't have primitives on the user side, only objects.
Mutability
There are two ways that you can declare a variable: val
and var
. val
is used when the variable should not change through the duration of your code, and by default, you should try to use val
whenever you can. If you do try to change the immutable variable, the compile will throw an error and you'll know at compile time. var
is used for variables that are allowed to be mutable.
Nullability
What makes Kotlin easier to work with compared to Java is that null checking happens during compile time instead of runtime. By default, variables in Kotlin are not nullable, and setting a variable to null will yield an error. To make a variable nullable, you'll need to add a ?
to the variable declaration like so var x?
or var x: String?
Objects
If that last example didn’t make any sense, don't worry -- we've got a quick overview of Kotlin's object system. An object type is always defined by a class and allows us to create instances of that class. For example the class Cat
we defined above allowed us to create the Cat
object a. The standard class file has three main things:
Instance variables
These are properties that are unique to each instance of an object. The instance variable type is shared among all objects but the value is different. For example, every cat has an age and a name, yet the values are different from cat to cat.
Constructor
The constructor is a special method that allows a programmer to create new instances of that class. Constructors typically update the instance variables of an object with specific values that are passed in, and are called as in the above example with:
If no constructor is defined for a class, Kotlin will create a default constructor that can take all the arguments detailed in the definition.
Methods
These are easily-repeatable chunks of code that typically perform some action using an object’s instance variables. Methods take arguments as inputs and can return a value as an output. Because Kotlin is statically-typed, we must define the types of the arguments and the return type when we create our method. Two methods are given for the Cat
class below:
The first method is an getter created for the value isNewborn
, which will return a true or false depending on the age. The second method roughly returns the birth year of the cat. Now, we can execute these methods on our cat a defined above.
Getters and Setters
Kotlin automatically creates getter and setter methods for instance variables inside of data classes. Look at the code below to see how to use these methods:
You can also override these methods:
Finally, you can also make getter and setter methods to private so that the method can only be used inside of its own class. This is a good way to protect the value of variables from being accidentally changed.
Modifiers
Modifiers place restrictions on variables, methods, and classes and exist before the static type, return type, or word ‘class’, respectively. Some common modifiers include:
public
/private
/protected
/internal
modifiers
public
/private
/protected
/internal
modifiersThese define the accessibility of a variable, method, or class in Kotlin. Something declared public can be accessed from anywhere within your project, something private can only be accessed from within the same class, something internal is within the same class and all it's subclasses, and something protected (i.e. method, class, variable) can be accessed from any file within the same package.
Inheritance
Kotlin is amazing because basically every class represents its own unique Object type -- forcing programmers into a coding style of separating functionality into different files. Kotlin also has a powerful system of inheritance, allowing programmers to reuse code in the most efficient way possible. This becomes especially prevalent in Android development, as many objects in the Android class system share a lot of functionality.
Subclasses
This technique allows us to further break down our classes into increasingly more specific types. For example, we could create a class representing a Sphynx
, and give it access to everything in Cat
without explicitly copying the code. By default, classes in Kotlin cannot be inherited from, to do you you must explicitly state that said class is open
.
Now we could create a Sphynx
object, and use all the methods and access the same instance variables from before. The super method call in the Sphynx
constructor above calls the Cat
constructor with arguments name and age, thereby setting the instance variables.
We can also create b by using Cat
as the static type of b
because this Sphynx is still a Cat
object (we told Java this with the extends keyword).
Method Overriding
Now, we can override certain methods of our parent Cat
class in Sphynx
. Overridden methods must have the exact same method signature as the parent method, with the same method name, return type, and argument types. Here is the overridden getName()
method:
Now, calling b.getBirthYear()
will throw a funny error.
Interfaces
Interfaces are special classes used for organizational purpose that cannot be instantiated. A class implements an interface, which forces the programmer to provide a method body for all the methods defined in the interface.
There are a few other Kotlin things you ought to be familiar with (initialization of arrays, conditionals, arithmetic operations, etc.), so we recommend you take a look at Kotlin Koans by the Kotlin team themselves! Otherwise, a solid foundation of Java will get you most of the way through understanding the concepts in Kotlin. With that being said, as with most things, practice makes perfect.
Last updated