All Basic of Kotlin
Kotlin is an open-source, general-purpose, statically typed programming language. It is an improved version of Java and is completely interoperable with it. Following are the features of Kotlin:-
Compact code: Kotlin is an OOPs-based programming language with code lines that may be reduced by up to 40% when compared to Java, making it an excellent choice for software development.
Open Source: Kotlin for Android is open-source and uses the JVM to combine the benefits of OOPs and functional programming.
Simple Language: When working with Kotlin, compiling the code is simple, resulting in improved performance for Android development. It also explains which types of data functions can be used throughout the code.
High number of extensions: Without modifying the code, Kotlin may support a variety of extension functions. It aids developers in making existing code more appealing and wonderful.
Full Java Interoperability: Java code can utilize Kotlin code, and Kotlin code can use Java code. So, if you're familiar with OOPS programming, switching to Kotlin development is simple. Also, if there are any Java-based applications, they can be used with Kotlin's environment.
Smart Cast: Smart casting is a technique that reduces the cost of an application while also improving its speed and performance. It uses typecasting or immutable data to manage the efficiency of programming. This technique is supported by Kotlin.
Low Learning Curve: Kotlin is preferred by businesses due to its low adoption cost. Most significantly, it is simple for developers to learn, especially if they have programming experience. Learn More.
1. What are the various data types available in Kotlin? Explain them.
Primitive data types are the most basic data types in Kotlin, and all others are reference types like array and string. Kotlin contains all data types as objects. Following are the different data types available in Kotlin:-


Integer Data Type -
Data Type Space Required byte 8 bits short 16 bits int 32 bits long 64 bits
Floating Point Data Type -
Data Type Space Required float 32 bits double 64 bits
Boolean Data Type -
True or false is the only bit of information represented by the Boolean data type. In Kotlin, the Boolean type is the same as in Java.
Data Type Space Required boolean 1 bit
Character Data Type -
Small letters (a-z), capital letters (A-Z), numerals (0-9), and other symbols are represented by the character data type.
Data Type Space Required char 8 bits
String Data Type -
Strings are represented in Kotlin by the type String. A string value is often a sequence of characters enclosed in double quotations ("). The space required in this case depends on the number of characters in the string.
Array Data Type -
The Array class in Kotlin is used to represent arrays. It has the get and set functions that, due to operator overloading conventions, can be used as ‘[]’ as well. The space required by the array also depends on the number of elements it posses
2. How are variables declared in Kotlin? What are the different types of variables in Kotlin? Explain with examples.
In Kotlin, you declare variables using the var or val keyword.
var (Mutable Variable): Can be reassigned after initialization.
kotlin
var myNumber: Int = 10 myNumber = 20 // Valid because 'var' allows reassignment
val (Immutable Variable): Once assigned, the value cannot be changed.
kotlin
val pi: Double = 3.14 // pi = 3.1415 // Error! 'val' variables cannot be reassigned
Type Inference: You can omit the data type if Kotlin can infer it.
kotlin
var greeting = "Hello, Kotlin!" // Type inference infers 'String'
Nullable Variables: Variables that can hold a null value are declared using ?.
kotlin
var name: String? = null
Here, name can either be a String or null.
Remember, var and val are used to declare variables, and you can specify the data type explicitly or let Kotlin infer it. Additionally, Kotlin introduces the concept of nullable types, allowing you to explicitly declare whether a variable can hold a null value.
3. What are data classes in Kotlin? Explain with a proper example.
In Kotlin, data classes are a concise way to declare classes that are mainly used to hold data. They automatically generate useful methods like toString(), equals(), and hashCode() based on the properties defined in the class. This simplifies the process of creating and working with classes that are primarily used to store data.
4. Explain the concept of null safety in Kotlin.
Kotlin null safety is a procedure to eliminate the risk of null reference from the code. Kotlin compiler throws NullPointerException immediately if it found any null argument is passed without executing any other statements.
Kotlin's type system is aimed to eliminate NullPointerException form the code. NullPointerException can only possible on following causes:
An forcefully call to throw NullPointerException();
An uninitialized of this operator which is available in a constructor passed and used somewhere.
Use of external java code as Kotlin is Java interoperability.
5. Explain Safe call, Elvis and Not Null Assertion operator in the context of Kotlin.
Sure, let's break down these concepts in Kotlin in a simple way:
1. Safe Call Operator (`?.`):
The safe call operator in Kotlin is `?.`. It's used to safely call a method or access a property on an object without risking a `NullPointerException`. If the object is `null`, the method won't be called, and the expression will result in `null`.
Example:
val length: Int? = text?.length
Here, if `text` is `null`, `length` will be `null` instead of causing a crash.
2. Elvis Operator (`?:`):
The Elvis operator in Kotlin is `?:`. It's used to provide a default value when an expression on the left side is `null`.
Example:
val length: Int = text?.length ?: 0
Here, if `text` is `null`, the default value of `0` will be assigned to `length`.
3. Not Null Assertion Operator (`!!`):
The not null assertion operator in Kotlin is `!!`. It's used to assert that an expression is non-null. If the expression on the left is `null`, it will throw a `NullPointerException`.
Example:
val length: Int = text!!.length
Use this with caution because if `text` is `null`, it will result in a runtime exception. It's generally recommended to use safe calls (`?.`) or the Elvis operator (`?:`) to handle nullability more safely.
In summary:
- Safe Call (`?.`): Use it to safely call methods or access properties on nullable objects.
- Elvis Operator (`?:`): Use it to provide a default value when an expression is null.
- Not Null Assertion (`!!`): Use it with caution; asserts that an expression is non-null and may throw a `NullPointerException` if it is null.
6. What are the different types of constructors available in Kotlin? Explain them with proper examples.
In Kotlin, there are mainly two types of constructors: Primary Constructors and Secondary Constructors.
### 1. Primary Constructor:
The primary constructor is declared in the class header itself. It can include properties and initialization code.
Example:
class Person(firstName: String, lastName: String) {
val fullName: String
init {
fullName = "$firstName $lastName"
}
}
In this example, `Person` class has a primary constructor with two parameters (`firstName` and `lastName`). The `init` block is used for initialization code.
Usage:
val person = Person("John", "Doe")
println(person.fullName) // Output: John Doe
### 2. Secondary Constructor:
Secondary constructors are additional constructors declared using the `constructor` keyword. They are used to provide alternative ways to create an object.
Example:
class Person {
val fullName: String
// Secondary Constructor
constructor(firstName: String, lastName: String) {
fullName = "$firstName $lastName"
}
}
Usage:
val person = Person("John", "Doe")
println(person.fullName) // Output: John Doe
It's worth noting that if a class has a primary constructor, each secondary constructor must delegate to the primary constructor, either directly or indirectly. This ensures that the initialization logic is consistent.
In summary, primary constructors are declared in the class header, and secondary constructors are declared with the `constructor` keyword inside the class body.
7. Explain the various methods to iterate over any data structure in Kotlin with examples.
In Kotlin, there are several ways to iterate over data structures like lists, arrays, and maps. Let's explore a few methods:
### 1. For Loop:
- Used for iterating over arrays and lists.
- Example:
val numbers = listOf(1, 2, 3, 4, 5)
for (number in numbers) {
println(number)
}
### 2. While Loop:
- Iterates as long as a condition is true.
- Example:
val numbers = listOf(1, 2, 3, 4, 5)
var index = 0
while (index < numbers.size) {
println(numbers[index])
index++
}
### 3. forEach Loop:
- A concise way to iterate over collections.
- Example:
val numbers = listOf(1, 2, 3, 4, 5)
numbers.forEach { number ->
println(number)
}
### 4. Map Iteration:
- Iterating over key-value pairs in a map.
- Example:
val ages = mapOf("Alice" to 25, "Bob" to 30, "Charlie" to 22)
for ((name, age) in ages) {
println("$name is $age years old")
}
### 5. Indices with 'forEachIndexed':
- Provides both the index and the value during iteration.
- Example:
val numbers = listOf(1, 2, 3, 4, 5)
numbers.forEachIndexed { index, number ->
println("Index $index: $number")
}
### 6. Range Iteration:
- Useful for iterating over a range of values.
- Example:
for (i in 1..5) {
println(i)
}
### 7. Iterating with 'repeat':
- Useful for repeating a block of code a specific number of times.
- Example:
repeat(3) {
println("Hello, Kotlin!")
}
Choose the method that best fits your needs based on the type of data structure and the iteration requirements.
8. How can you concatenate two strings in Kotlin?
Following are the different ways by which we can concatenate two strings in Kotlin:
Using String Interpolation:- We use the technique of string interpolation to concatenate the two strings. Basically, we substitute the strings in place of their placeholders in the initialisation of the third string.
val s1 = "Interview"
val s2 = "Bit"
val s3 = "$s1 $s2" // stores "Interview Bit"
Using the + or plus() operator:- We use the ‘+’ operator to concatenate the two strings and store them in a third variable.
val s1 = "Interview"
val s2 = "Bit"
val s3 = s1 + s2 // stores "InterviewBit"
val s4 = s1.plus(s2) // stores "InterviewBit"
Using StringBuilder:- We concatenate two strings using the StringBuilder object. First, we append the first string and then the second string.
val s1 = "Interview"
val s2 = "Bit"
val s3 = StringBuilder()
s3.append(s1).append(s2)
val s4 = s3.toString() // stores "InterviewBit"
9. What do you understand about function extension in the context of Kotlin? Explain.
Kotlin extension function provides a facility to "add" methods to class without inheriting a class or using any type of design pattern. The created extension functions are used as a regular function inside that class.
Explanation:
In general, we call all methods from outside the class which are already defined inside the class.In below example, a Student class declares a method is Passed() which is called from main() function by creating the object student of Student class. Suppose that we want to call a method (say isExcellent()) of Student class which is not defined in class. In such situation, we create a function (isExcellent()) outside the Student class as Student.isExcellent() and call it from the main() function. The declare Student.isExcellent() function is known as extension function, where Student class is known as receiver type.
class Student{
fun isPassed(mark: Int): Boolean{
return mark>40
}
}
fun Student.isExcellent(mark: Int): Boolean{
return mark > 90
}
fun main(args: Array<String>){
val student = Student()
val passingStatus = student.isPassed(55)
println("student passing status is $passingStatus")
val excellentStatus = student.isExcellent(95)
println("student excellent status is $excellentStatus")
}
Output:
student passing status is true
student excellent status is true
10. What do you understand about Companion Object in the context of Kotlin?
In Kotlin, a Companion Object is like a shared space for a class where you can put properties and methods that are related to the class itself rather than instances of the class.
Here's a simple way to understand it:
Imagine you have a class called Car. Now, every car has some common features, right? Like the number of wheels or the type of fuel. Instead of repeating these for each car you create, you can use a Companion Object.
kotlin
class Car(val brand: String, val model: String) {
// properties specific to each car instance
companion object {
// properties and methods shared by all Car instances
fun startEngine() {
println("Engine started!")
} } }
In this example, brand and model are specific to each car you create, but startEngine() is common for all cars. You can call it without creating an instance of Car:
kotlin
Car.startEngine() // prints "Engine started!"
So, think of a Companion Object as a place to put things that are related to the class as a whole, not to any particular instance of the class. It helps keep your code organized and avoids unnecessary repetition.
11. Differentiate between open and public keywords in Kotlin.
In Kotlin, both open and public are keywords used for different purposes.
open Keyword:
It is used to declare a class, function, or property that can be subclassed or overridden in derived classes.
When you mark a class or a function with open, it means that other classes can inherit from it or override its methods.
Example:
open class Animal {
open fun makeSound() {
println("Some generic sound")
} }
class Dog : Animal() {
override fun makeSound() {
println("Woof! Woof!")
} }
public Keyword:
In Kotlin, all classes, functions, and properties are public by default.
When you declare something as public, it means it is accessible from anywhere in the same module or package.
Example:
// This class is public by default
class Car {
public fun start() {
println("Car started")
} }
In summary, open is used for allowing inheritance and overriding, while public is the default visibility modifier, making entities accessible within the same module or package.
12. Explain about the “when” keyword in the context of Kotlin.
Certainly! In Kotlin, the `when` keyword is used as a replacement for the traditional `switch` statement in some other languages. It's a powerful tool for handling multiple conditions in a concise and expressive way.
Here's a simple explanation:
kotlin
fun main() {
val day = 3
val result = when (day) {
1 -> "Monday"
2 -> "Tuesday"
3 -> "Wednesday"
4 -> "Thursday"
5 -> "Friday"
else -> "Weekend"
}
println("It's $result")
}
In this example:
- We have a variable `day` with a value of `3`.
- The `when` expression checks the value of `day`.
- If `day` is 1, it prints "Monday"; if it's 2, it prints "Tuesday," and so on.
- If none of the specified conditions match, it falls back to the `else` branch, printing "Weekend."
This makes the code more readable and concise compared to a series of `if-else` statements or a `switch` statement. The `when` expression can also be used for other types of checks, like checking types or ranges. It's a versatile tool for handling different scenarios in your Kotlin code.
13. Kotlin Control Flow Statements
Control flow statements in Kotlin allow you to direct the order of execution of statements in your program. These statements are essential for making decisions, looping through code, and managing the flow of your application. This chapter will cover the different types of control flow statements available in Kotlin, along with examples and their syntax.
Types of Control Flow Statements
1. if Statement
The if statement is used to execute a block of code if a specified condition is true.
2. if-else Statement
The if-else statement provides an alternative block of code to execute if the specified condition is false.
3. if-else if-else Statement
The if-else if-else statement allows you to test multiple conditions.
4. when Statement
The when statement is used to replace multiple if-else if statements. It is similar to the switch statement in other languages.
5. for Loop
The for loop is used to iterate over a range, array, or collection.
6. while Loop
The while loop is used to repeatedly execute a block of code as long as the specified condition is true.
7. do-while Loop
The do-while loop is similar to the while loop, but it guarantees that the block of code will be executed at least once.
8. break Statement
The break statement is used to terminate the loop or the nearest enclosing loop immediately.
9. continue Statement
The continue statement is used to skip the current iteration of the loop and proceed to the next iteration.
14. Kotlin Functions
Functions are a fundamental concept in programming that allow you to encapsulate a block of code into a reusable unit. In Kotlin, functions are declared using the fun keyword.
Types of Functions
1. Default Arguments
You can provide default values for function parameters. If an argument is not passed, the default value is used.
fun main() {
greet()
greet("Alice")
}
fun greet(name: String = "Guest") {
println("Hello, $name!")
}
Explanation:
fun greet(name: String = "Guest") { ... }: Declares a function named greet with a default value for the name parameter.
greet(): Calls the greet function without arguments, using the default value.
greet("Alice"): Calls the greet function with the argument "Alice".
2. Named Arguments
You can specify arguments by name when calling a function. This improves readability and allows you to pass arguments in any order.
3.Higher-Order Functions
Higher-order functions are functions that take other functions as parameters or return functions.
fun main() {
val result = performOperation(5, 3, ::add)
println("Result: $result")
}
fun add(a: Int, b: Int): Int {
return a + b
}
fun performOperation(a: Int, b: Int, operation: (Int, Int) -> Int): Int {
return operation(a, b)
}
Explanation:
fun performOperation(a: Int, b: Int, operation: (Int, Int) -> Int): Int { ... }: Declares a higher-order function named performOperation that accepts a function as a parameter.
::add: Passes the add function as an argument to performOperation.
15. Kotlin Recursive Functions
A recursive function is a function that calls itself in order to solve a problem. Recursion is a powerful technique for solving problems that can be broken down into smaller, similar subproblems.
Basic Recursive Function
A basic recursive function in Kotlin calls itself with modified arguments until a base condition is met. The base condition is necessary to stop the recursion and prevent infinite loops.
Tail-Recursive Function
A tail-recursive function is a special form of recursion where the recursive call is the last operation in the function. Tail recursion can be optimized by the compiler to avoid stack overflow errors for deep recursion.
16. Kotlin Lambda Function
Lambda functions, also known as anonymous functions or function literals, are a concise way to define functions in Kotlin. They can be passed as arguments, returned from other functions, and stored in variables.
17. Kotlin Arrays
Arrays in Kotlin are a collection of items of the same type. Arrays are used to store multiple values in a single variable, making it easier to manage and manipulate collections of data.
18. Kotlin Strings
Strings in Kotlin are objects that represent sequences of characters. They are immutable, meaning that once a string is created, its value cannot be changed. Kotlin provides a rich set of methods and properties to manipulate strings effectively.
19. Kotlin Object-Oriented Programming (OOP)
Object-Oriented Programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data and methods. Kotlin is a modern, statically typed programming language that supports OOP principles such as classes, objects, inheritance, polymorphism, and encapsulation.
Kotlin Classes and Objects
Classes and objects are fundamental concepts in object-oriented programming (OOP). A class defines a blueprint for an object, and an object is an instance of a class.
Creating Objects
An object is an instance of a class. You create an object by calling the class constructor.
Properties and Methods
Properties: Properties are variables that belong to a class. They can be mutable (var) or immutable (val).
Methods: Methods are functions that belong to a class and define the behavior of objects.
Visibility Modifiers: Kotlin provides visibility modifiers to control the visibility of classes, objects, interfaces, constructors, functions, properties, and their setters.
public: The public modifier is the default visibility in Kotlin. A public member is accessible from anywhere in the code.
private: The private modifier restricts the visibility to the declaring class or file. A private member is accessible only within the class or file where it is declared.
protected: The protected modifier allows visibility to the declaring class and its subclasses. A protected member is accessible within its class and subclasses.
internal: The internal modifier restricts the visibility to the same module. An internal member is accessible within the same module.
Kotlin Constructors
Constructors are special functions used to initialize objects in Kotlin. They are called when an instance of a class is created. Kotlin supports two types of constructors: primary and secondary.
Primary Constructor: The primary constructor is part of the class header and is used to initialize properties. It is concise and can have optional parameters with default values.
Secondary Constructor: A class can have one or more secondary constructors. They are prefixed with the constructor keyword and are used to provide additional ways to initialize objects.
Initializer Blocks: Initializer blocks are used to initialize properties and execute code when an instance of the class is created. They run after the primary constructor.
Kotlin Encapsulation
Encapsulation is a fundamental concept in object-oriented programming (OOP) that restricts direct access to an object’s internal state and allows modification only through well-defined methods. This helps to protect the integrity of the object’s data and makes the code more modular and maintainable.
Encapsulation in Kotlin involves:
Defining a class with private properties.
Providing public methods to access and modify the properties.
Using custom getters and setters to control how properties are accessed and modified.
Benefits of Encapsulation
Data Hiding: Internal state of an object is hidden from the outside, preventing unauthorized access and modification.
Modularity: Changes to the internal implementation of a class do not affect the code that uses the class.
Maintainability: Well-defined interfaces make the code easier to understand, maintain, and extend.
Kotlin Inheritance
Inheritance is a fundamental concept in object-oriented programming (OOP) that allows a class to inherit properties and methods from another class. The class that inherits is called the subclass (or derived class), and the class being inherited from is called the superclass (or base class). In Kotlin, inheritance allows for code reuse and the creation of hierarchical class structures.
Inheritance in Kotlin :
To define a class as inheritable in Kotlin, you need to use the open keyword. By default, classes in Kotlin are final and cannot be inherited. The subclass uses the : symbol followed by the superclass name to indicate inheritance.
Kotlin Interfaces
Interfaces in Kotlin define a contract that classes can implement. They can contain abstract methods as well as method implementations. Unlike classes, interfaces cannot store state, and a class can implement multiple interfaces, which helps in achieving multiple inheritances.
Defining an Interface
To define an interface in Kotlin, use the interface keyword. Interfaces can contain both abstract methods (which do not have a body) and concrete methods (which have a default implementation).
Kotlin Abstract Classes and Methods
An abstract class cannot be instantiated and may contain abstract methods that must be implemented by subclasses. Abstract methods are defined without a body and must be overridden in the subclasses.
Kotlin Data Classes
Data classes in Kotlin are a special kind of class designed to hold data. They provide a concise syntax for defining classes whose primary purpose is to store values.
To define a data class, use the data keyword before the class keyword. A data class must have at least one primary constructor parameter.
Kotlin Sealed Classes
Sealed classes in Kotlin are a special type of class that allow you to represent restricted class hierarchies. When a value can have one of a limited set of types, you can use a sealed class to define it.
Defining a Sealed Class:To define a sealed class, use the sealed keyword before the class keyword. Sealed classes can have subclasses, but all subclasses must be defined in the same file as the sealed class.
Benefits of Sealed Classes
Exhaustive when Expressions: Since all possible subclasses of a sealed class are known at compile time, when expressions can be exhaustive, ensuring that all cases are handled.
Type Safety: Sealed classes provide better type safety by restricting the hierarchy to a known set of subclasses.
Kotlin Polymorphism
Polymorphism in programming is the ability for the same piece of code (like a function or method) to work in different ways depending on the situation.
Types of PolymorphismCompile-time polymorphism (Static polymorphism): Achieved through method overloading.
Run-time polymorphism (Dynamic polymorphism): Achieved through method overriding.
Compile-time Polymorphism (Method Overloading)
Method overloading is a feature that allows a class to have more than one method with the same name, but with different parameters.
Run-time Polymorphism (Method Overriding)
Method overriding occurs when a subclass provides a specific implementation for a method that is already defined in its superclass.
20. Kotlin Exception Handling
Exception handling is a mechanism to handle runtime errors, ensuring that the normal flow of the program is not disrupted. Kotlin provides a robust mechanism for handling exceptions using try, catch, finally, and throw keywords.
Throwing Exceptions: You can throw an exception explicitly using the throw keyword.
Multiple Catch Blocks: You can use multiple catch blocks to handle different types of exceptions.
try { ... }: Contains code that may throw an exception.
catch (e: ArithmeticException) { ... }: Catches the exception and handles it.
finally { ... }: Contains code that will always execute, regardless of whether an exception is thrown or not.
Try Catch : The try-catch block is used to handle exceptions, ensuring that the program continues running even when an error occurs.
Finally Block: The finally block in Kotlin is used in conjunction with try and catch blocks to execute code regardless of whether an exception is thrown or not. The finally block is useful for releasing resources, closing connections, or performing any cleanup operations that need to be executed after a try-catch block.
21. Kotlin Collections
Collections in Kotlin are used to store groups of related objects. Kotlin provides a variety of collection types, such as lists, sets, and maps, that can hold multiple items.
These collections come in two variants: mutable and immutable. Immutable collections cannot be modified after they are created, while mutable collections can be.
Kotlin Lists :
Lists in Kotlin are ordered collections of elements that can contain duplicates.
Kotlin provides two types of lists: List for immutable lists and MutableList for mutable lists.
Lists are commonly used for storing and manipulating collections of related data.
Kotlin Sets:
Sets in Kotlin are unordered collections of unique elements.
Unlike lists, sets do not allow duplicate elements.
Kotlin provides two types of sets: Set for immutable sets and MutableSet for mutable sets.
Kotlin Maps
Maps in Kotlin are collections of key-value pairs where each key is unique, and each key maps to exactly one value.
Maps are useful for storing data that can be quickly retrieved using a key.
Kotlin provides two types of maps:
Map for immutable maps.
MutableMap for mutable maps.
22. Kotlin Null Safety
Null safety is a key feature in Kotlin designed to eliminate the danger of null references, commonly known as the "billion-dollar mistake". Kotlin provides several mechanisms to handle nullability in a safe and concise way.
Nullable Types: In Kotlin, types are non-nullable by default. If you want a variable to hold a null value, you must explicitly declare it as nullable by appending a question mark (?) to the type.
Safe Call Operator (?.): The safe call operator (?.) allows you to access properties and methods of a nullable object without risking a null pointer exception. If the object is null, the expression returns null.
Elvis Operator (?:): The Elvis operator (?:) provides a default value if the expression to the left is null. It is a concise way to handle nullability and provide a fallback value.
Safe Cast Operator (as?): The safe cast operator (as?) attempts to cast a value to a specified type. If the cast is not possible, it returns null instead of throwing an exception.
Non-Null Assertion Operator (!!): The non-null assertion operator (!!) converts any value to a non-null type and throws a NullPointerException if the value is null. Use this operator only when you are sure that the value is not null.
let Function: The let function is an extension function that executes a block of code only if the object is not null. It can be used with the safe call operator.
23. Kotlin Generics
Generics in Kotlin allow you to create classes, interfaces, and functions that can operate on any data type while maintaining type safety. Generics enable you to write more flexible and reusable code.
Generic Classes: A generic class is a class that can work with any data type. You define a generic class by placing a type parameter in angle brackets after the class name.
Generic Functions: A generic function is a function that can operate on any data type. You define a generic function by placing a type parameter in angle brackets before the function name.