Android – 5 Quick Valuable Concepts To Learn Kotlin Programming Language

Hello Readers, CoolMonkTechie heartily welcomes you in this article (5 Quick Valuable Concepts To Learn Kotlin Programming Language).

In this article, We will learn about Valuable Concepts To Learn Kotlin Programming Language. At Google I/O 2019, Google announced that Android development will be increasingly Kotlin-first, and we’ve stood by that commitment. Kotlin is an expressive and concise programming language that reduces common code errors and easily integrates into existing apps. If we’re looking to build an Android app, we recommend starting with Kotlin to take advantage of its best-in-class features. This article shows the kotlin fundamental for android application development

For understanding the basic fundamental concepts of kotlin, we will explore the below topics one by one:

  • Variable declaration
  • Conditionals
  • Functions
  • Classes
  • Interoperability

A famous quote about learning is :

” Develop a passion for learning. If you do, you will never cease to grow.”

So Let’s begin.


1. Variable declaration

Kotlin uses two different keywords to declare variables: val and var.

  • Use val for a variable whose value never changes. We can’t reassign a value to a variable that was declared using val.
  • Use var for a variable whose value can change.

In the example below, count is a variable of type Int that is assigned an initial value of 10:

var count: Int = 10

Int is a type that represents an integer, one of the many numerical types that can be represented in Kotlin. Similar to other languages, we can also use ByteShortLongFloat, and Double depending on our numerical data.

The var keyword means that we can reassign values to count as needed. For example, we can change the value of count from 10 to 15:

var count: Int = 10
count = 15

Some values are not meant to be changed, though. Consider a String called languageName. If we want to ensure that languageName always holds a value of “Kotlin”, then we can declare languageName using the val keyword:

val languageName: String = "Kotlin"

These keywords allow us to be explicit about what can be changed. Use them to our advantage as needed. If a variable reference must be reassignable, then declare it as a var. Otherwise, use val.


Type inference

Continuing the previous example, when we assign an initial value to languageName, the Kotlin compiler can infer the type based off of the type of the assigned value.

Since the value of "Kotlin" is of type String, the compiler infers that languageName is also a String. Note that Kotlin is a statically-typed language. This means that the type is resolved at compile time and never changes.

In the following example, languageName is inferred as a String, so we can’t call any functions that aren’t part of the String class:

val languageName = "Kotlin"
val upperCaseName = languageName.toUpperCase()

// Fails to compile
languageName.inc()

toUpperCase() is a function that can only be called on variables of type String. Because the Kotlin compiler has inferred languageName as a String, we can safely call toUpperCase()inc(), however, is an Int operator function, so it can’t be called on a String. Kotlin’s approach to type inference gives us both conciseness and type-safety.


Null safety

In some languages, a reference type variable can be declared without providing an initial explicit value. In these cases, the variables usually contain a null value. Kotlin variables can’t hold null values by default. This means that the following snippet is invalid:

// Fails to compile
val languageName: String = null

For a variable to hold a null value, it must be of a nullable type. We can specify a variable as being nullable by suffixing its type with ?, as shown in the following example:

val languageName: String? = null

With a String? type, we can assign either a String value or null to languageName.

We must handle nullable variables carefully or risk a dreaded NullPointerException. In Java, for example, if we attempt to invoke a method on a null value, our program crashes.

Kotlin provides a number of mechanisms for safely working with nullable variables.


2. Conditionals

Kotlin features several mechanisms for implementing conditional logic. The most common of these is an if-else statement. If an expression wrapped in parentheses next to an if keyword evaluates to true, then code within that branch (i.e. the immediately-following code that is wrapped in curly braces) is executed. Otherwise, the code within the else branch is executed.

Example : if / else

if (count == 42) {
    println("I have the answer.")
} else {
    println("The answer eludes me.")
}

We can represent multiple conditions using else if. This lets us represent more granular, complex logic within a single conditional statement, as shown in the following example:

if (count == 42) {
    println("I have the answer.")
} else if (count > 35) {
    println("The answer is close.")
} else {
    println("The answer eludes me.")
}

Conditional Expressions

Conditional statements are useful for representing stateful logic, but we may find that we repeat ourself when writing them. In the example above, we simply print a String in each branch. To avoid this repetition, Kotlin offers conditional expressions. The last example can be rewritten as follows:

val answerString: String = if (count == 42) {
    "I have the answer."
} else if (count > 35) {
    "The answer is close."
} else {
    "The answer eludes me."
}

println(answerString)

Implicitly, each conditional branch returns the result of the expression on its final line, so we don’t need to use a return keyword. Because the result of all three branches is of type String, the result of the if-else expression is also of type String. In this example, answerString is assigned an initial value from the result of the if-else expression. Type inference can be used to omit the explicit type declaration for answerString, but it’s often a good idea to include it for clarity.

We aware that Kotlin does not include a traditional ternary operator, instead favoring the use of conditional expressions.

As the complexity of our conditional statement grows, we might consider replacing our if-else expression with a when expression, as shown in the following example:

val answerString = when {
    count == 42 -> "I have the answer."
    count > 35 -> "The answer is close."
    else -> "The answer eludes me."
}

println(answerString)

Each branch in a when expression is represented by a condition, an arrow (->), and a result. If the condition on the left-hand side of the arrow evaluates to true, then the result of the expression on the right-hand side is returned. Note that execution does not fall through from one branch to the next. The code in the when expression example is functionally-equivalent to that in the previous example but is arguably easier to read.

Smart Casting

Kotlin’s conditionals highlight one of its more powerful features, smart casting. Rather than using the safe-call operator or the not-null assertion operator to work with nullable values, we can instead check if a variable contains a reference to a null value using a conditional statement, as shown in the following example:

val languageName: String? = null
if (languageName != null) {
    // No need to write languageName?.toUpperCase()
    println(languageName.toUpperCase())
}

Within the conditional branch, languageName may be treated as non-nullable. Kotlin is smart enough to recognize that the condition for executing the branch is that languageName does not hold a null value, so we do not have to treat languageName as nullable within that branch. This smart casting works for null checkstype checks, or any condition that satisfies a contract.


3. Functions

We can group one or more expressions into a function. Rather than repeating the same series of expressions each time that we need a result, we can wrap the expressions in a function and call that function instead.

To declare a function, use the fun keyword followed by the function name. Next, define the types of inputs that our function takes, if any, and declare the type of output that it returns. A function’s body is where we define expressions that are called when our function is invoked.

Building on previous examples, here’s a complete Kotlin function:

fun generateAnswerString(): String {
    val answerString = if (count == 42) {
        "I have the answer."
    } else {
        "The answer eludes me"
    }

    return answerString
}

The function in the example above has the name generateAnswerString. It doesn’t take any input. It outputs a result of type String. To call a function, use its name, followed by the invocation operator (()). In the example below, the answerString variable is initialized with the result from generateAnswerString().

val answerString = generateAnswerString()

Functions can take arguments as input, as shown in the following example:

fun generateAnswerString(countThreshold: Int): String {
    val answerString = if (count > countThreshold) {
        "I have the answer."
    } else {
        "The answer eludes me."
    }

    return answerString
}

When declaring a function, we can specify any number of arguments and their types. In the example above, generateAnswerString() takes one argument named countThreshold of type Int. Within the function, we can refer to the argument by using its name.

When calling this function, we must include an argument within the function call’s parentheses:

val answerString = generateAnswerString(42)


Simplifying function declarations

generateAnswerString() is a fairly simple function. The function declares a variable and then immediately returns. When the result of a single expression is returned from a function, we can skip declaring a local variable by directly returning the result of the if-else expression contained in the function, as shown in the following example:

fun generateAnswerString(countThreshold: Int): String {
    return if (count > countThreshold) {
        "I have the answer."
    } else {
        "The answer eludes me."
    }
}

We can also replace the return keyword with the assignment operator:

fun generateAnswerString(countThreshold: Int): String = if (count > countThreshold) {
        "I have the answer"
    } else {
        "The answer eludes me"
    }


Anonymous functions

Not every function needs a name. Some functions are more directly identified by their inputs and outputs. These functions are called anonymous functions. We can keep a reference to an anonymous function, using this reference to call the anonymous function later. We can also pass the reference around our application, as with other reference types.

val stringLengthFunc: (String) -> Int = { input ->
    input.length
}

Like named functions, anonymous functions can contain any number of expressions. The returned value of the function is the result of the final expression.

In the example above, stringLengthFunc contains a reference to an anonymous function that takes a String as input and returns the length of the input String as output of type Int. For that reason, the function’s type is denoted as (String) -> Int. This code does not invoke the function, however. To retrieve the result of the function, we must invoke it with like we would a named function. We must supply a String when calling stringLengthFunc, as shown in the following example:

val stringLengthFunc: (String) -> Int = { input ->
    input.length
}

val stringLength: Int = stringLengthFunc("Android")


Higher-order functions

A function can take another function as an argument. Functions that use other functions as arguments are called Higher-order functions. This pattern is useful for communicating between components in the same way that we might use a callback interface in Java.

Here’s an example of a higher-order function:

fun stringMapper(str: String, mapper: (String) -> Int): Int {
    // Invoke function
    return mapper(str)
}

The stringMapper() function takes a String along with a function that derives an Int value from a String that we pass into it.

We can call stringMapper() by passing a String and a function that satisfies the other input parameter, namely a function that takes a String as input and outputs an Int, as shown in the following example:

stringMapper("Android", { input ->
    input.length
})

If the anonymous function is the last parameter defined on a function, we can pass it outside of the parentheses used to invoke the function, as shown in the following example:

stringMapper("Android") { input ->
    input.length
}

Anonymous functions can be found throughout the Kotlin standard library. 


4. Classes

All of the types mentioned so far are built into the Kotlin programming language. If we would like to add our own custom type, we can define a class using the class keyword, as shown in the following example:

class Car


Properties

Classes represent state using properties. A property is a class-level variable that can include a getter, a setter, and a backing field.

Since a car needs wheels to drive, we can add a list of Wheel objects as a property of Car, as shown in the following example:

class Car {
    val wheels = listOf<Wheel>()
}

Note that wheels is a public val, meaning that wheels can be accessed from outside of the Car class, and it can’t be reassigned. If we want to obtain an instance of Car, we must first call its constructor. From there, we can access any of its accessible properties.

val car = Car() // construct a Car
val wheels = car.wheels // retrieve the wheels value from the Car

If we want to customize our wheels, we can define a custom constructor that specifies how our class properties are initialized:

class Car(val wheels: List<Wheel>)

In the example above, the class constructor takes a List<Wheel> as a constructor argument and uses that argument to initialize its wheels property.


Class functions and encapsulation

Classes use functions to model behavior. Functions can modify state, helping us to expose only the data that we wish to expose. This access control is part of a larger object-oriented concept known as encapsulation.

In the following example, the doorLock property is kept private from anything outside of the Car class. To unlock the car, we must call the unlockDoor() function passing in a valid key, as shown in the following example:

class Car(val wheels: List<Wheel>) {

    private val doorLock: DoorLock = ...

    fun unlockDoor(key: Key): Boolean {
        // Return true if key is valid for door lock, false otherwise
    }
}

If we would like to customize how a property is referenced, we can provide a custom getter and setter. For example, if we would like to expose a property’s getter while restricting access to its setter, we can designate that setter as private:

class Car(val wheels: List<Wheel>) {

    private val doorLock: DoorLock = ...

    var gallonsOfFuelInTank: Int = 15
        private set

    fun unlockDoor(key: Key): Boolean {
        // Return true if key is valid for door lock, false otherwise
    }
}

With a combination of properties and functions, we can create classes that model all types of objects.


5. Interoperability

One of Kotlin’s most important features is its fluid interoperability with Java. Because Kotlin code compiles down to JVM bytecode, our Kotlin code can call directly into Java code and vice-versa. This means that we can leverage existing Java libraries directly from Kotlin. Furthermore, the majority of Android APIs are written in Java, and we can call them directly from Kotlin.

That’s all about in this article.


Conclusion

In this article, We understood about Valuable Concepts To Learn Kotlin Programming Language. Kotlin is a flexible, pragmatic language with growing support and momentum. We discussed about Kotlin fundamental like variable declaration, function, conditions and classes concepts which is widely used by Android developers everywhere for application development. This article showed the basic Kotlin fundamental concepts for android application development

Thanks for reading ! I hope you enjoyed and learned about the basic fundamental concepts of Kotlin for android development. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe to the blog and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

You can find Other articles of CoolMonkTechie as below link :

You can also follow official website and tutorials of Android as below links :

If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.

Thanks again Reading. HAPPY READING !!???

Loading

Summary
Android - 5 Quick Valuable Concepts To Learn Kotlin Programming Language
Article Name
Android - 5 Quick Valuable Concepts To Learn Kotlin Programming Language
Description
This article covers Valuable Concepts To Learn Kotlin Language which is used by Android developers everywhere for application development.
Author

Leave a Comment