Java To Kotlin Part 2 — Classes And Methods

Michael Duivestein
Tech@Travelstart
Published in
4 min readOct 17, 2018

Part 1 showed you how to declare and extend classes, create constructors, and create methods.

Part 2 will build on Part 1. Even though it compiles to the JVM, Kotlin works a little differently to Java. It has a few different types of classes, which are useful for certain situations. It also has some really nifty built-in features.

Expected outcome of part 2:
This should give a good understanding of the different types of class/object available to a Kotlin developer, and how they can all co-exist in the same file. This section also covers some basic Kotlin method features, like default arguments and overriding classes.

This simple Employee Java class will be used as an example of what’s possible:

This is what the equivalent Kotlin class looks like (Excluding the last four methods, as it’s not a data class):

Add the Department enum:

(Enums in Kotlin differ from Java only by the class keyword)

The Kotlin compiler will add invisible getters and setters to a class. This is explained below.

Data Classes

The Employee class can be refined further as a data class:

Data classes exist for one single purpose: To store data. By design, data classes are final and cannot be extended. Data classes also come with a few extra built-in methods:

(This will be covered a bit later)

When compared to an identically functional Java class, a Kotlin class is a lot more compact. There’s virtually no boilerplate to type, and it comes with some nifty methods. Imagine all the time saved when writing a whole module! Add to that all the time saved in not having to maintain all that boilerplate code…

A brief note on Getters and Setters

In a class, when a property is created, Kotlin generates invisible getters and setters. They’re considered invisible because we invoke the property instead of the getter/setter. This gets translated to a getter/setter call. When accessing a Kotlin property in Java, the getter/setter is called as per normal. An advantage of this system is that, if a property needs to be mutated during get/set, the property can be made private and a custom getter/setter can be added.

Multiple public classes in a single file

This is a good place to point out that Kotlin supports multiple public classes in a single file (So does Java, just with non-public classes*):

*Something many developers don’t know is that Java supports multiple classes in a single file. The only difference between Java and Kotlin is that Java only allows a single public class in a file.

Best practices:

As with all systems, multiple classes in one file can be abused. According to the Kotlin Style Guide, if a file contains multiple classes, the name of the file should describe the contents of a file. This implies that only classes and functions with similar functionality should be placed in the same file together.

copy()

As mentioned earlier, data classes contain a built-in copy() method:

The copy method does more than just making a carbon copy:

This allows us to make copies of immutable classes, while giving us the ability to alter the data.

Constructors with default arguments

Both class constructors and method signatures can take default values as part of their arguments. For instance, in Employee, the name parameter is nullable and the default value is null. We can, therefore, instantiate this class in two different ways:

Let’s use another example:

Methods work identically (And it should as class constructors are methods):

Default arguments are most useful in situations where a variable should not be null and can take a default value.

Overriding methods with default values

When overriding methods that contain default values, the parent’s default values can be omitted:

Constructors and methods with named arguments

This is another of Kotlin’s interesting features. It has a way to call a method with args in a different order. The trick is to name them (And IntelliJ’s auto-complete helps with this):

Mixing named args and default values in a method signature can unlock some really useful and powerful options for smart, clean code.
It’s also useful to note that one can also keep the args in order..

Single-line methods

Any single-method can be condensed into an one line method. This looks like an assignment. For instance:

can be converted to:

Companion Objects

Companion objects are a type of singleton that gets added to a class. They act like a container for methods and properties:

Accessing a method in a companion object from outside of it’s class works the same way as Java statics, except for the fact that companion objects are singletons.

In the beginning, Kotlin can feel a little strange to a Java developer. For instance, it allows multiple classes to be added to a single file. To make things even crazier, one can add functions to a file… outside of a class:

These functions can be used in other files. They can be imported on a per-function basis:

Package-level functions can also be imported on a per-package basis:

Package-level functions are always static.

This concludes Part 2. The above points should point you in the right direction to mastering Kotlin. As usual, a smart IDE should help you to improve on these points.

Examples for Part 2 can be found here.
The Employee java class example can be found here.
The external function imports example can be found here.

Part 3 of the series can be found here.

Originally published at k0ma.co.za on October 17, 2018.

--

--