Posts

Kotlin Type Checking and Smart Cast with Examples

Image
  Type Checking in Kotlin For certain scenarios, we need to check the type of the object i.e. we need to identify the class of the object before executing any function on that object. Consider a scenario where you have different types of objects in an array. You are looping on that array and executing some functionality. If you call a method that does not exist in the object, an error will be thrown at the runtime. To prevent such errors, we do type checking. In Kotlin, we have an  " is operator"  that helps in checking the type of the object. fun main() { var p1 = Person() if(p1 is Person) // Use of is operator { p1.sayHi() } } class Person{ fun sayHi() = println("Hi") } Explanation -  Here, we are checking the type of p1 instance that if it is of type Person - call its sayHi() method. In this case, it is evident that the object is of type Person only but for scenarios where we need to check the type - we use an "is operator".

Kotlin Interfaces With Example

Image
We can group classes based on what they are i.e. based on inheritance. The circle is a shape, Square is a shape - these classes belong to the Shape hierarchy because they are Shapes. We can also group classes based on what they do or what behavior they exhibit. A circle object can be dragged, a person object can be dragged - here we have grouped classes Circle and Person based on the behavior dragging . Even if the classes do not belong to a single class hierarchy, we can group them based on the behavior. This is where Interfaces come into the picture. Interface -  When you want your class to exhibit certain behavior irrespective of the class hierarchy they belong to - Use Interface. Interfaces help you to implement polymorphism based on the behavior defined in the interface. Methods defined in the interfaces are 100% abstract but in Kotlin you can also define methods that are non-abstract i.e. methods can have a body. Non-abstract methods in interfaces do not have any state they can r

Kotlin Abstract Class With Examples

Image
What are Abstract Classes ? A class that cannot be instantiated i.e. we cannot create the objects of an abstract class. Generally used as a parent class that defines the common protocol for the child classes. What are Abstract Methods? Abstract methods are those methods that do not have a body. These methods can only be defined inside an abstract class i.e. if you mark the method as abstract, you need to mark that class as abstract. Let's understand this with an example -  Suppose, we have this class hierarchy and we need to display these shapes and there is a method to calculate the area of these shape objects. We know how to display a square, a circle, or a triangle. But what about shape? If we define a shape class as a normal class - we can also create an instance of this Shape class. But there is a problem here. We don't know how a Shape looks like and we cannot even calculate its area because we don't know how it looks. So does it make sense to allow users to create a

Polymorphism in Kotlin With Example

Image
Polymorphism is one of the most important topics in Object-Oriented Programming. It goes hand in hand with Inheritance . Poly means many and morph means forms i.e. the same method behaves differently based on the object. Here we have different forms of the method that exhibits different behavior based on the object. To define Polymorphism in simple words - A parent can hold a reference to its child and can call methods which are provided by the parent class. Let's understand this with an example -  fun main() { val circle : Shape = Circle(4.0) val square : Shape = Square(4.0) } open class Shape{ open fun area() :Double{ return 0.0 } } class Circle(val radius:Double) : Shape(){ override fun area(): Double { return Math.PI * radius * radius } } class Square(val side:Double) : Shape(){ override fun area(): Double { return side * side } } Explanation -   Here we have defined a Shape class which is a base class and open for i

Overriding in Kotlin and Any Class

Image
Overriding in Kotlin Methods and properties defined in the parent class can be used in child classes using Inheritance. This prevents code duplication as child classes can re-use the functionality provided by the parent. But sometimes, we don't want to use the same behavior provided by the parent - we want to override a few of the methods that are specific to the child's class. We can do so using the override keyword in Kotlin. To make this work, we have to mark the property or method in the parent class as open and then in the child can we can override that. Let's see this in action -  fun main() { val square = Square() println(square.name) square.display() } open class Shape { open var name: String = "Shape" open fun display() = println("Shape is displayed") } class Square: Shape() { override var name: String = "Square" override fun display() = println("Square is displayed") } Explanation

Kotlin Inheritance With Example

Image
What is Inheritance? Just like in real life, we inherit features and behaviors from our parents. Our parents inherit from their grandparents. We can apply this same logic in programming.  While designing the classes we can extract out common properties and behavior in a separate class and other classes that require these features will inherit from this class - this will create a parent-child relationship among the classes. In simple words, Inheritance is a way of organizing code in a parent-child relationship that helps in reducing code duplication. You define the functionality in a parent class that will be inherited by child classes. You don't need to define the same functionality in a child class - child classes will have it from its parent. Inheritance in Kotlin Inheritance in Kotlin is no different than any other programming language that supports Object-Oriented Programming.  But in Kotlin, if you want to allow a class to be inheritable, you have to explicitly mark it as Open

Kotlin Getters And Setter + LateInit

Image
  Kotlin Getters & Setters With Example If you want to execute some logic before setting or getting the property of an object, you can use getters and setters.  You can consider these as functions that are executed when you either get the property or set the property of an object. But why we want to do this? Why we want to execute code before accessing it? Let's understand this with an example -  fun main() { val user = User("John", 20, "abc@cheezycode.com") user.age = -10 } class User(nameParam: String, ageParam: Int, emailParam: String) { var name : String = nameParam var age: Int = ageParam var email: String = emailParam } Explanation -  Here we have defined a User class - inside the main function, we are setting the value of age to a negative value.  In a real-world scenario, you don't want any user to have negative age. So you also want to prevent this in your code. You don't want anybody to set a negative value to a