In this section, we will learn the concept of abstraction and how they work on classes, functions and properties in Kotlin.
What is Abstract Class in Kotlin?
Abstract classes are those type of classes that allow us to define a set of members (properties or functions) but leave out their body and let the child classes to inherit and implement those members.
Basically, using the abstract classes, we can create a Parent class that defines a set of protocols if you will and let the Child classes to practically implement those protocols.
Alright, the best way to understand abstract classes is by seeing and using them practically, so let’s go and first see how we can create an abstract class and then we move on to see how to use them in practice.
How to Create an Abstract Class in Kotlin?
This is how we can create an abstract class in Kotlin
abstract class Class_Name{ //Instructions… }
abstract
: to create an abstract class, we start with the keyword abstract.
After that, the rest of an abstract class is pretty much the same as a normal class (AKA concrete class).
Within the body of abstract classes, we can put abstract properties and functions which will be explained in the rest of this section.
Notes:
- You can’t create an object directly from an abstract class!
- An abstract class still can have typical members that we define in normal classes.
- An abstract class can become the data type of variable that is holding an object that was created from a child in that abstract class.
- Abstract classes are by default open and so you don’t need to set it to open when we want to make that class as the parent of another class.
Example: creating an abstract class in Kotlin
abstract class Person{ //Intructions... } class Employee: Person(){ //Instructions... } fun main(){ var emp = Employee() }
Here you can see that the abstract class Person is now inherited by the Employee class. Note that we didn’t set the open keyword in front of the Person class! This is again because abstract classes are by default, open.
What is an Abstract Property in Kotlin?
An abstract property is the one that we just declare without any sort of initialization. Basically, abstract properties are created when we want to make sure every child class that inherits from the abstract class has a set of properties and each sets its own body for those properties (This means child classes must override the abstract properties).
Notes:
- Abstract properties can only be used in the body of an abstract class.
- Again, when creating an abstract property, it is the responsibility of the child classes to initialize those abstract properties.
How to Create an Abstract Property in Kotlin?
This is how we create an abstract property in Kotlin:
abstract class ClassName{ abstract var variableName:data-type }
abstract
: again to create an abstract property in an abstract class, we prefix the variable with the `abstract` keyword.
var/val
: an abstract property can be created using either val or var keywords.
As you can see, we didn’t assign any value to these variables! In fact, if we do so, we will get an error.
Note:
- It is the responsibility of the child classes to override the abstract properties using the override keyword and instantiate them.
- Abstract properties are by default open and so we don’t need to put this keyword in front of the properties in order to make the child classes be able to override them.
Example: creating abstract property in Kotlin
abstract class Person{ abstract val firstName:String abstract var lastName:String } class Employee(fName:String, lName:String): Person(){ override val firstName:String = fName override var lastName:String = lName } fun main(){ var emp = Employee("John","Doe") println(emp.firstName) println(emp.lastName) }
Output:
John Doe
Here you can see we have two abstract properties named firstName and lastName and then both of these variables are overridden using the override keyword in the Employee
class.
Note that if we didn’t override these properties, we would’ve got an error.
What is an Abstract Function in Kotlin?
Now abstract functions are like abstract properties and we create them when we want to make sure those child classes inherit and override these functions in order to make their own body for the abstract functions.
How to Create an Abstract Function in Kotlin?
This is how we create an abstract function in Kotlin:
abstract class ClassName{ abstract fun functionName(parameters...) }
Again, we use the abstract keyword to create an abstract function.
Everything of an abstract function is the same as a normal function, with the exception that we don’t set a body for an abstract function!
Note:
- abstract functions are open by default and so we don’t need to prefix them with the
open
keyword. - We use the override keyword to override an abstract function in a child class.
Example: creating abstract functions in Kotlin
abstract class Person{ abstract val firstName:String abstract var lastName:String abstract fun printFullName() } class Employee(fName:String, lName:String): Person(){ override val firstName:String = fName override var lastName:String = lName override fun printFullName(){ println("The name is $firstName and last name is $lastName") } } fun main(){ var emp = Employee("John","Doe") emp.printFullName() }
Output:
The name is John and last name is Doe
As you can see, the printFullName() function is an abstract class in the Person class and we’ve overridden this function in the Employee class.
Abstract Classes and Inheritance from each other
Note that abstract classes can inherit from each other! In that case, child abstract classes don’t need to override the abstract members (properties or functions). But of course there’s no limit on that and we can override a parent member in the body of a child abstract class if there’s a need for it.
Example: an abstract class inheriting from another abstract class
abstract class Person{ abstract val firstName:String abstract var lastName:String abstract fun printFullName() } abstract class Employee(fName:String, lName:String): Person(){ override val firstName:String = fName override var lastName:String = lName } class Manager(firstName:String,lastName:String): Employee(firstName,lastName){ override fun printFullName(){ println("The name is $firstName and last name is $lastName") } } fun main(){ var emp = Manager("John","Doe") emp.printFullName() }
Output:
The name is John and last name is Doe
Here you can see that the two properties are overridden in the Employee class, which is an abstract class, but then the printFullName
function is overridden in the body of the Manager class, which is a concrete one.
Notes:
- Throughout this section we only used abstract properties and functions in an abstract class, but you’re more than welcome to put normal properties and functions in such type of classs. Also, for these properties and functions, you don’t need to use abstract keyword and hence the child classes are not obligated to override them.
- Also note that abstract classes can have constructors as well. The only thing is that we can use these constructors within child classes to instantiate the parent class only! Basically, we can’t use them to create an object from an abstract class.