Book Image

Hands-On Object-Oriented Programming with Kotlin

By : Abid Khan, Igor Kucherenko
Book Image

Hands-On Object-Oriented Programming with Kotlin

By: Abid Khan, Igor Kucherenko

Overview of this book

Kotlin is an object-oriented programming language. The book is based on the latest version of Kotlin. The book provides you with a thorough understanding of programming concepts, object-oriented programming techniques, and design patterns. It includes numerous examples, explanation of concepts and keynotes. Where possible, examples and programming exercises are included. The main purpose of the book is to provide a comprehensive coverage of Kotlin features such as classes, data classes, and inheritance. It also provides a good understanding of design pattern and how Kotlin syntax works with object-oriented techniques. You will also gain familiarity with syntax in this book by writing labeled for loop and when as an expression. An introduction to the advanced concepts such as sealed classes and package level functions and coroutines is provided and we will also learn how these concepts can make the software development easy. Supported libraries for serialization, regular expression and testing are also covered in this book. By the end of the book, you would have learnt building robust and maintainable software with object oriented design patterns in Kotlin.
Table of Contents (14 chapters)

Flow controls

Programming is the execution of different operations, and the flow control is an operation to control the execution of these operations. By using this, a programmer can decide how a program should behave or what section of code should be executed at a given time. Like other programming languages, Kotlin provides several structures that allow the control to be implemented.

We will now explore each of the flow controls in the following sections.

The if statement

The if statement can be perceived as a filter method that is designed to channel the relevant data, and further operate, drive, or act on that information.

As with most programming languages in common practice, there are code blocks that are dependent on certain parameters, variables, and conditions that may only execute when a certain situation is true or false. if statements are used when a decision needs to be made; this works with Boolean logic, which means that the conditions defined for an if can only have two outcomes, true and false:

if (a > b) {
max = a
}

When an if statement is present and the condition is true, the primary code block is executed. If not, the code block is ignored, as we can see in the following example:

fun main(args: Array<String>) {
val langName = "Kotlin"
if ( langName == " Kotlin" ) {
println ( "Hello"+ langName)
}
}

The result would display as Hello Kotlin. When the value of the langName variable is anything other than Kotlin, the code block under the if statement would not be executed.

The if and else statements

The if and else statements have been around for a long time, and almost all languages are dependent on these types of conditional statements for filtering information. When the condition is satisfied, the primary code block will be executed. If the condition fails, the else statement comes into play.

Let's see an example of how this works:

fun main(args: Array<String>) {

val langName = "Java"
if ( langName == "Kotlin" ) {
println ( "I love "+ langName )
}
else {
println ("The name of the language is "+ langName )
}
}

If the langName variable is assigned a "Kotlin" string, then the first code block of the if statement will be executed. If not, the else statement will be executed.

The if statement with a conditional operator

When we work in real time, more often than not the if statement is used to break down complex scenarios and define the flow without getting into the hassle of checking each individual condition separately. To reduce code complexity and encourage better implementation of program flow, we can use conditional operators to combine or group prerequisites into a single if condition to filter and execute the relevant code block.

The conditions can be combined or grouped in an if statement by using the and (&&), or (||) and not(!) operators.

The if statement with the and (&&) operator

The and (&&) operator is used for absolute results. The and operator returns true if and only if all conditions grouped together are satisfied. In the event that either conditions fail to satisfy the grouped condition, the if statement will fail and the respective code block will be ignored until the grouped condition is satisfied as a whole.

An if statement with an && operator can be written in ampersand form:

var studentMarks = 92
if (studentMarks >= 90 && value < 96) {
println ("A")
}

The and operator can also be written in word form:

if ((studentMarks >= 90) and (value < 96)) {
println ("A")
}

The if statement with the or (||) operator

The or (||) operator is a fairly lenient operator which returns true when either of the two conditions in the group is true. The if statement fails when both conditions are not satisfied and skips the respective code block until one of the grouped conditions is satisfied. The if with || operator can be written in symbol form:

if ((b > a) || (b > c)) {
println("b is a winner")
}

The or operator can be written in word form:

if (b > a or b > c) {
println("b is a winner")
}

The if statement with the (!) Not operator

The Not operator, represented by an exclamation mark, !, is used when the condition with a NOT operator is true if the returning value is false. The Not operator also makes it possible to easily check if the condition is not true, in which case, the following result should be displayed:

if(a!=b) {
println("a and b are different")
}

if as an expression

Kotlin has introduced a new feature called if as an expression, which makes a programmer's life much easier. Instead of assigning a value in each if statement, Kotlin returns the value from a successful code block, which can be stored in a variable. Before writing an if statement, add a variable name with an assignment operator as follows:

grade = if (studentMarks >= 90) {
"A"
}

See the following example with if as an expression, where grade will be assigned depending on studentMarks:

fun main(args: Array<String>) {
val studentMarks = 95
var grade = if (studentMarks >= 90) {
"A"
} else if (studentMarks >= 80) {
"B"
} else if (studentMarks >= 70) {
"C"
} else if (studentMarks >= 60) {
"D"
} else {
"F"
}
println ( "Student achieved " + grade )
}

Notice that it is not required to write grade = "A" or grade = "D" in each else…if block, but while using if as an expression, there is one thing to remember—if as an expression cannot be used without an else statement:

val grade = if (studentMarks >= 90) {
"A"
}

Kotlin will throw the following compile-time error:

'if' must have both main and 'else' branches if used as an expression

The When expression

Kotlin provides an alternative method to the if statement—the When expression. When can also be perceived as a filter method. This is similar in nature to the Switch statement in Java or C. When sequentially matches its arguments with all branches until a condition is satisfied for a branch.

The When expression works as follows:

  • When can use arbitrary expressions and constants.
  • It takes the variable in the expression and matches the value within the branches.
  • If the condition for the variable is a match, the relevant code block of the branch will execute. If none of the other branch conditions are satisfied, the else branch is evaluated.

Writing the When statement:

  • The When statement is followed by the expression defined within the parenthesis: when (expression).
  • A branch is a condition followed by a code block. This is defined as {condition -> code block} and appears after the expression contained within the curly brackets.
  • The else branch is mandatory with its own code block contained within the curly brackets.
  • If there is no else branch in the when, all possible cases must be covered in the branches so that the compiler can validate all of the branches.

Write a program by using when as an expression to display the day on its corresponding number, 1 for Monday, 2 for Tuesday, and so on:

fun main(args: Array<String>) {
val day = 2
when(day) {
1-> println("Monday")
2-> println("Tuesday")
3-> println("Wednesday")
4-> println("Thursday")
5-> println("Friday")
6-> println("Saturday")
7-> println("Sunday")
else -> println("Invalid input")
}
}

To verify and test various conditions, assign different values to the day variable. The program will display the respective day according to the value or error message if the input is out of range. We can rewrite the student grade program by using the when expression.

Combining cases

The When expression allows us to combine more than one cases in one line. In order to match with the expression, we concatenate more than one case in a comma-separated list:

fun main(args: Array<String>) {
val grade = "b"
when (grade) {
"A","a" -> println("Excellent")
"B","b" -> println("Very Good")
"C","c" -> println("Nice work")
"D","d" -> println("OK")
"E","e" -> println("Hmmm")
"F","f" -> println("Better luck next time")
else -> println("Invalid input")
}
}

In this example, a user can enter the student's grade without worrying about whether the keyboard caps lock is on or off. If input is "a" or "A", either way the output will be Excellent.

Ranges with When

It is also possible to match cases in range form. To make use of ranges, Kotlin provides the in operator. Using the in operator, we are asking for a value that is contained within a given range. This is specifically useful when more than one condition has the same result:

fun main(args: Array<String>) {
val grade = "A"
when (grade) {
in "A".."E" -> println("You are promoted to the next level")
"F" -> println("You need hard work.")
else -> println("Invalid input")
}
}

In this example, if the student grade is within the range of A to E then a You are promoted to the next level message will be displayed. If the grade is F, then You need hard work. will be displayed on the screen; otherwise, Invalid input is displayed.

When as an expression

Similarly to the if statement, when can also be used as an expression. To do this, create a variable and assign when as an expression as follows:

fun main(args: Array<String>) {
val grade = "A"
val remarks = when (grade) {
"A","a" -> "Excellent"
"B"
,"b" -> "Very Good"
"C"
,"c" -> "Nice work"
"D"
,"d" -> "OK"
"E"
,"e" -> "Hmmm"
"F"
,"f" -> "Better luck next time"
else -> "Invalid input"
}
println(remarks)
}