Kotlin is a more modern version of Java. It adopts functional ideas such as immutability and first-class functions, out of the box, and it is also object oriented. It aims to reduce the ‘noise’ that Java has and so make programs more concise and readable. It also aims to reduce some of the standard errors that are part of normal Java coding. This course introduces you to Kotlin and will get you up to speed very quickly so that you can adopt this language in your projects.
Modules in Solid Kotlin:
Introduction to Kotlin
This chapter gives a brief introduction to Kotlin and examines some of the problems it is trying to solve. We cover some language basics and the tooling available.
Getting Started with Kotlin
Kotlin is both an object oriented and a functional language. This chapter introduces both of these concepts. Starting with the obligatory “Hello, World” we show how to write a simple application and then talk about variables and immutability; classes; properties; accessors; visibility; basic language concepts such as looping, expressions and ranges. We also examine how Kotlin is able to throw and handle exceptions.
Functions in Kotlin
Kotlin extends and improves functions in Java in a number of ways, for example there is support for both named and default parameters, we cover both of those here. Kotlin supports ‘top-level’ functions, that is static functions that are declared at the package level, not in a class, this negates the need for ‘Util’ style classes that just contain helper methods. There is also support for ‘extension’ methods and properties, this provides a way of adding methods and properties to existing classes without needing the source code for that class, these are similar to extension methods in C# if you are used to that language.
Programming with Types
In this chapter we cover how to write OO code in Kotlin. We look at how to define interfaces and classes and how to create objects. Interfaces in Kotlin are like interfaces in Java 8, they support default methods, but they also support properties. Kotlin classes are similar to Java’s but follow the principal that classes should be ‘final’ by default and only explicitly ‘opened’, we look at this property and examine the ramifications of this.
Kotlin provides the concept of a ‘primary’ constructor which is defined outside the class body, and secondary constructors defined as part of the class, we will show how to set up and use all the constructor types.
Kotlin supports the idea of ‘data’ classes, these are classes that are used in containers such as maps and lists. These classes typically require you to override equals and hashCode and a ‘data’ class in Kotlin does this automatically.
Kotlin also has ‘Sealed’ classes. These allow us to restrict class hierarchies. We show how to create sealed class hierarchies and how to use them.
Finally we cover the ‘Any’, ‘Nothing’ and ‘Unit types that don’t exist in Java, explaining where they fit into the Kotlin type hierarchy and how they are used.
The ‘object’ keyword provides a way to declare a class and create an instance of it at the same time.
This is useful if, for example, you want to create singletons. We show in this chapter how this keyword works and where to use it.
Kotlin classes cannot have static members, you would typically use package-level functions instead. However, if those functions need access to the private data of a class they won’t work, in that case you need to use ‘companion objects’ we see how to create these and show the various usage patterns for them.
Lambdas in Kotlin
This chapter covers how Kotlin declares and uses Lambdas. Lambdas have been around in programming languages for many, many years and were finally added to Java in Java 8, released in 2015. Lambdas are essentially small pieces of behaviour and simplify and shorten code.
Kotlin lambdas provide access to variables in scope and so can create ‘closures’, we will explain these and see them in action.
We will also see the use of ‘with’ and ‘apply’ from the standard Kotlin library. We show how to use member references and examine the syntax. Kotlin supports higher-order functions that is both being able to pass functions as parameters to
other functions and also returning functions from functions. In this chapter, we examine Kotlin’s support for higher-order functions
Filtering and Sorting Data (Map and Related Functions)
Lambdas provide an easy syntax for working with collections. We have ‘functional’ concepts such as map, filter, any, all and groupBy.
Working with Infinite Collections
Kotlin supports ‘Sequences’ which are very similar to Java 8 streams but are available on platforms where streams are not (such as Android). We see in this chapter how to use Sequences in Kotlin
Java Functional Interfaces
Java 8 introduced the idea of ‘Functional Interfaces’ Kotlin lambdas interact with these interfaces and this chapter we see how that happens and look at some of the details of using functional interfaces
Nullability in Kotlin
Kotlin has the concept of ‘Nullable Types’ Nullable types in Kotlin provide information to the compiler about whether a null value is allowed and so helps the compiler to guard against null pointer exceptions. It provides operators to help with null values such as the safe call operator (?.), the ‘Elvis’ operator (?:) and the safe cast operator (as?) Kotlin has to interoperate with Java. In this chapter, we discuss what happens when we combine Kotlin and Java
Collections in Kotlin can hold Nullable types. In this chapter we see how such collections work. Kotlin collections can be used in both a read-only and a mutable way, i.e. Kotlin splits the collection behaviours across two interfaces, one providing read-only access and the other adding the necessary functionality to update the collection. We also look at how Kotlin collections interact with Java.
Kotlin Collection Classes
Kotlin supports both mutable and immutable collections. In this chapter we look at how to create and use these collections including lists, arrays and maps. We also examine how nullability affects collections
Higher Order Functions
In this chapter we take a closer look at ‘higher-order’ functions in Kotlin. We cover how to declare function types and where these types are used as variables. We examine how lambdas are typically ‘expanded’ in code and how we can improve the efficiency in same cases by creating ‘in-line’ functions
Generics were added to Java in version 1.2. Kotlin also supports generics. In this chapter, we look at how to declare generics; we look at inlining; we also look at Kotlin’s support for reifying generics, that is not having they type information erased at compile time. Finally, we look at Generic variance in Kotlin, that is how collections of related types relate to each other