This is a multi-part series on Kotlin, a new statically typed language from JetBrains targeting the JVM and JavaScript
A small but important note
Kotlin is still work in progress and not all design decisions are final. That is why your feedback is fundamental. So please provide any feedback via this blog, via our forums, via twitter on what you like, what you dislike.
Declaring variables
Before diving into classes, let’s first see how we can declare variables in Kotlin, as we’ll eventually need to do so when creating an instance of our class. In Kotlin, variables can be declared in one of two ways, using the var or val keyword:
- var declares a variable that is mutable, that is, the value can change after it has been assigned
- val declares a variable that is immutable, that is, once assigned the value cannot change
Notice that we have not declared the type. Much like the var keyword in C#, since the variable has been initialized, the compiler can infer the type. However, if we do not initialize the variable, we need to explicitly define the type:
What happens however when we declare an immutable type that has not been initialized?
As expected, the compiler will allow us to set the value, but not change it. So all is good.
Knowing now the difference between val and var, let’s move on and look at classes.
Classes
Classes are the main building blocks for many object-orientated programming languages, and as such, of Kotlin also. An empty class declaration looks pretty much like that in C# and Java
(If you’re using IntelliJ, you will see items highlighted in the gutter with an icon and letter. In this case C represents Class)
Classes can be public, private, protected or internal. By default they are internal to modules (we’ll cover what modules and accessibility levels are later). This has the initial apparent disadvantage that you would not be able to test your code from outside a module. The team is currently working on a solution for this which would involve building modules in a specific way that would allow test projects to call internal classes. The approach however will not be the same as in C# where the attribute internalsVisibleTo is required. To use a class, we merely create an instance of it. new keyword does not exist in Kotlin. A constructor call is similar to a function call.
Note that this customer has a default constructor that takes no parameters, which in Kotlin is a known as the primary constructor. We can override this primary constructor by defining a constructor as part of the class definition
with the actual implementation contained inside the anonymous initializer. This anonymous initializer is actually only necessary when we need certain logic. If we are merely using the constructor to initialize properties, we do not need it.
Now that we know how to create a class and define constructors, let’s add some contents to the class.
Properties
Usually classes in C# and Java are composed of fields, properties, methods and nested classes. In Kotlin, classes can contain properties, methods, nested classes and object declarations. We’ll cover this last one further along in the series. However, the key thing here to notice is that Kotlin does not allow fields. As such, everything is a property. It can be internal (default), private, protected or public.
Here we have one internal property and two public ones. Notice how the internal one does not have an explicit type declaration. It is not needed. However, if we were to remove the type declaration for one of the public properties, we’d get a compiler error
The reason for this is to prevent unintentional breakage of a public API, since it’s much more likely to change the type of a property without realizing the impact it might have if it’s not explicit. Another thing to notice is that all properties require explicit initialization, irrelevant of their accessibility or whether they are mutable (var) or immutable (val).
Was that an AutoProperty?
If you’re a C# developer you’re no doubt familiar with the autoproperties, whereby the compiler internally has a backing field holding the value of a property, without requiring you to define explicit getters and setters unless you want to define explicit behavior. Kotlin is pretty much the same in that way and what we just saw uses an internal backing field which is called the same as the property but prefixed with the character $
Custom Getters and Setters
What happens when we want to provide custom behavior when reading or writing to properties? In these cases we can define getters and setters
This is an example of a customer getter which always returns “Always Jack” as the value of the property Name irrelevant of what value it has. Notice how we just define it below the property. If our getter requires more than one line, we can use a { } block. Much like the getter, we can also define a setter. In this setter, we can write any logic that interacts with other properties of the class. But what happens when we want to interact with the actual backing field of this property (the one that the compiler creates automatically)? as mentioned before, we can use the $ prefix to access it
Setters can have different accessibility levels, by prefixing them with the corresponding keyword.
Functions
Although we won’t dive too deeply into all the different aspects of functions in this part (otherwise it would be too long of a blog post), we will see the basics to create functions as part of our classes. A function declaration, in its simplest form is:
consisting of the function name, optional parameters, optional return type and the body. Functions in Kotlin return tuples, that is they can return more than one value. When we do not specify a return type, we are implicitly saying that the return type is a Unit which is a tuple with 0 components. Below is a full example of a class that takes two parameters in the constructor, initializes some properties and contains a function the prints out the full name.
We’ll dive deeper into functions and all the possibilities they offer in a different post.
Summary
In this second part, we’ve covered the basics of classes, how to declare one, how constructors work and how to define properties and functions. Classes in Kotlin however offer much more and there’s a lot more to learn about them. In other parts we’ll cover the difference between open and final classes (hint: default is final), abstract classes, inheritance, as well as traits, which are somewhat similar to interfaces in C#.