Language Elements

Data Types

Kotlin Nullable Types

Extension Functions

Lambda Functions

Object Oriented Kotlin

Data Classes

Coroutines

Collections

Kotlin Example Codes

Kotlin Interview Questions


Kotlin and Java

Kotlin shares several core language elements with Java, including classes, objects, interfaces, and many common data types, and both support object-oriented programming features. However, Kotlin introduces key differences, such as:

Data types

Kotlin supports data types:

  • Numbers: Includes Byte, Short, Int, Long, Float, and Double.
  • Booleans: Represents true or false.
  • Characters: Single characters, represented using the Char type.
  • Strings: Sequence of characters, represented using the String type.
  • Arrays: Collections of elements of the same type, represented using the Array class.
  • Like Java and C++, Kotlin is also statically typed language, so the type correctness of variables and expressions is determined at compile time. The Kotlin compiler catches type errors.

    Kotlin can use type inference, where the compiler can infer the type of a variable based on the assigned value, eliminating the need for explicit type declarations. Though it is a common choice in Kotlin, explicit type declarations are better where they improve clarity. Type inference enhances code readability and conciseness, making it a common choice in Kotlin. Explicit type declarations are recommended in situations where they improve clarity or help avoid ambiguity.

    Variable declaration

    Variables are used to store values for a specific data type. For mutable types, key word var is used and for immutable types, either val (compile time values) or const (run type values) is used.

         
       var: Int = 2
       
       or, simply using Kotlin's type inference
       
       var = 2 
       
       var can be assigned different value (read-write).
       
       val: String = "This is Kotlin tutorial"
       
       or, using type inference
       
       val = "This is Kotlin tutorial"
       
       val here, is immutable (read-only), equivalent to, as final in Java.
       
       val flag:booleanValue = true
    
       val pi: Double = 3.14
       
       val charValue: Char = 'A'
       
       val intArray: Array = arrayOf(1, 2, 3, 4, 5,6)
       
       val list: List = listOf(1, 2, 3, 4, 5,6)
       
       val set: Set = setOf("apple", "carrot", "orange")
       
      val map: Map = mapOf(1 to "one", 2 to "two", 3 to "three")
      
      val intRange: IntRange = 1..15
      
      val charRange: CharRange = 'A'..'Z'
      
    

    All above decalred with explicit data type can also be declared by removing it, using type inference, where appropriate.

    Note above that Kotlin statements does not require a semicolon (;) to end the statement like many other programming languages, such as Java, C++, etc.

    Comments

    
        // This is single line Kotlin comment
        
       /*   This is 
       *    multi-line Kotlin comment
       */
       
    

    Functions

    Functions - Functions or Methods in Kotlin are declared by key word fun.

    Main Function - This function declared as fun main() is the entry point for a Kotlin program.

         
        fun main() { 
        
        println("Kotlin Tutorial at www.zyasin.com!")
    }

    Top-Level Function - These are directly defined in the file and are not tied to any specific class or instance. Above defined 'fun main()' is an example of a top-level function in Kotlin. They encapsulate functionality not tied to a specific class, and generally used for utility functions, helper functions or entry point of a program. They improve code readability and maintability.


    Functions as Expressions

    Class

    To define a Kotlin class use class key word, followed by class name.

         
         
    class ClassName {
        
     
        //declare properties (using key words val or var.)
        
        
        //declare functions (using key word fun.)
        
        
    }
       
    

    Default Kotlin classes are final and can't be extended unless declared with open key word.

    Kotlin provides visibility modifiers like private, protected, internal, and public to control the visibility of class members. By default, class members are public.

    Abstract Class

    For an abstract class in Kotlin, no instance can be created. It is open by default (can't be final!) and can be sub-classed by other non-abstract classes to provide the desired functionality. Abstract methods and fields of abstract class are declared with abstract key word and not final by default, so can be overriden in the implementing class. Any non-abstract members of an abstract class are final by default, which can be only be overriden in child class, once declared as open.

    Constructor

    For proper object initialization, a Kotlin class can have Primary and Secondary constructors.

    Primary Constructor: It is the main way to initialize the properties of a class, defined as part of the class header and responsible for initializing the properties when an object of class is created. To declare a primary constructor keyword constructor can be optionally added just after the class name. The primary constructor defined with the class header do not contain any code. Initialization code is placed within initializer blocks, inside the class body prefixed with the init keyword.
        
    class ClassName(parameters) {
        
     
        //declare properties (using key words val or var.)
        
        
        // initializer blocks
        
        
    }
       
    
    Secondary Constructor:

    A class can have none, one or more secondary constructors. The secondary constructors are created using the constructor keyword. They allow initialization of variables and can provide some logic to the class. One common use of secondary constructor is when extending a class providing multiple cinstructors which each initializing the class in a different way. Compiler decides which constructor to pick based on arguments.

        
        class Student(val studentId: Int, val firstName: String, val lastName: String) {
        val fullName: String
    
        init {
            fullName = "$firstName $lastName"
        }
    
         // Secondary costructor
        constructor(firstName: String, lastName: String) : this(0, firstName, lastName)
    }
        
        
        
    Here the Student class has a secondary constructor that takes only firstName and lastName parameters. The secondary constructor delegates to the primary constructor using the this keyword and provides a default value of 0 for the studentId parameter. This allows to create Student objects without specifying a student ID.

    Instance

    To define a Kotlin instance or object, call the constructor of class like a regular function i.e. for class Chair, an instance can be declared as var chair = Chair(). Properties and function of a class can be accessed using . notation i.e. name of instance followed by dot and some property or function of class.

    Interface

    In Kotlin, interfaces can contain method implementation as well as abstract methods and properties declaration. An interface needs to be implemented by a class in order for any use. In Kotlin interfaces are not implicitly final. Interfaces can be implemented by any class without any restrictions. However, interface can be forced to be final by using "final" key word before them, which then prevent other classes from implementing it or inheriting from it, however it is extremely rare cases where such need can arise.

         
        
    interface KotlinInterface {
    
        var someString: String        // abstract property
    
        fun someFunction()            // abstract method
       
        fun string() = "Some string"  // method with default implementation
    }
    
    
    To implement above interface in a class:
         
        
    class ImplementKotlinInterface : interface KotlinInterface {
    
        override var someString: String = "some string"        // property declared in interface implemented 
    
        override fun someFunction() = "display string outpt"   // function declared in interface implemented
        
        override fun string() = "Some string text overriden"   // text in method of interfce overridden 
        
        
        
    }
    
    

    Control Flow


  • if, else if, else: Conditional branching.
  •      
    val x = 14
    if (x > 14) {
        println("x is greater than 14")
    } else if (x == 14) {
        println("x is equal to 14")
    } else {
        println("x is less than 14")
    }
         
  • when: More versatile, but like switch in Java.
  • 
    val x = 3
    when (x) {
        1 -> println("x is 1")
        2 -> println("x is 2")
        else -> println("x is neither 1 nor 2")
    }
    
    
  • for, while, do-while: Loops for iteration.
  •   
       for (i in 1..5) {
        println(i)
    }
       
       
  • return: Used to exit a function and optionally provide a value to the caller. Return value must match the expected return type of function.
  •  
     fun isPositive(number: Int): Boolean {
        if (number > 0) {
            return true
        } else {
            return false
        }
    }
     
     
  • break: Used within loops (such as for, while, and do-while) to terminate the loop and program control moves to the code after the loop.

  • for (i in 1..10) {
        if (i == 5) {
            break
        }
        println(i)
    }
    
    
  • continue: Breaks the loop iteration in between by skipping the part next to the continue statement till end of the loop and continues to next iteration.
  •      
         for (i in 1..5) {
        if (i == 3) {
            continue
        }
        println(i)
    }
        
    

    Quiz Questions


  • What is difference between use of"val" and "const" in Kotlin?
  • Can "const" be used with "var"?
  • Can "const" be used as local variable?
  • What are key differences between "Abstract Class" and "Interface" for Kotlin?
  • What problem occurs for inherting an abstract class if declared "final"?
  • Can properties and methods of a Kotlin abstract class be "final"?
  • Can a Kotlin interface has non-abstract methods?
  • Does Kotlin allows to implement multiple interfaces in a single class?



  • Copyright © by Zafar Yasin. All rights reserved.