In this article, you will learn about Kotlin abstract classes, abstract methods and how to use them in our program with the help of examples.
Abstract Classes
An abstract class is a class that cannot be instantiated (we cannot create objects of an abstract class).
Syntax
We use the abstract keyword to declare an abstract class.
abstract class className { //properties and functions }
If we try to create objects of an abstract class, we will get a compilation error. For example,
//abstract class abstract class Person { //class members var name: String = "Arun Kumar" fun show() { println("Name: $name ") } } fun main(args: Array<String>) { //creating Person instance //error: cannot create an instance of an abstract class val person = Person() }
We can access the members of a class by creating its object or by creating an object of its subclass.
Abstract classes cannot be instantiated but we can create subclasses from it. We can create objects of subclasses to access members of the abstract class.
Abstract class is used to define common characteristics of subclasses and the only purpose of the abstract class is to let other sub classes inherit from it.
Before we learn about it in detail, we need to understand abstract members.
Abstract Members
Abstract classes can contain properties that are not initialized called abstract properties and methods that contains no implementation (without any body) called abstract methods.
We use the same keyword abstract to create abstract member (abstract property or abstract function).
//abstract class abstract class Vehicle { //abstract variable abstract var fuel: String //not initialized //abstract function abstract fun start() //no implementation }
An abstract class can contain both abstract and non-abstract members as shown below:
abstract class Vehicle(val fuelType: String) { // non-abstract Property abstract var fuelCapacity: Int // abstract Property abstract fun start() // abstract function abstract fun stop() // abstract function fun park() { // non-abstract function println("Vehicle is in park mode") } }
Note: Abstract classes and abstract members are always open. You do not need to explicitly use open keyword.
Overriding abstract members
An abstract class cannot be instantiated; therefore we must inherit it so that we can access the members of an abstract class.
When an abstract class is inherited,
- To create an object of subclass, we must have to override (provide implementation to a method already defined in superclass) all the abstract members of super class in our subclass.
- However, if subclass does not implement abstract members, then the subclass must also be declared abstract (now subclass cannot be instantiated).
Example
//abstract class abstract class Person(val name: String, val rollNo: Int) { // non-abstract property // abstract property (Must be overridden by Subclasses) abstract var caste: String // abstract function (Must be implemented by Subclasses) abstract fun dateOfBirth(date: String) // non-abstract method fun show() { println("Student Name: $name") println("Roll No: $rollNo") println("Caste: $caste") } } //derived class inheriting Person class class Student(name: String, rollNo: Int) : Person(name, rollNo) { //abstract property caste is initialized override var caste = "OBC" //implementation of abstract function dateOfBirth override fun dateOfBirth(date: String) { println("Date of Birth is: $date") } } fun main(args: Array<String>) { val student = Student("Arun Kumar", 100) student.show() student.dateOfBirth("02 July 1995") }
Output
Student Name: Arun Kumar Roll No: 100 Caste: OBC Date of Birth is: 02 July 1995
Example explained
- Person is an abstract class which contains abstract members ( caste (property) and dateOfBirth (function)) and non-abstract members ( name, rollNo (properties) and show (function)).
- Student class is inherited from the super class Person. The subclass (Student) overriding the abstract members of the Person class.
- Now creating an instance of subclass we cannot only access its members, but we can also access its superclass(Person) members (abstract and non-abstract).
Overriding a non-abstract open member with an abstract one
In Kotlin, we can override the non-abstract open members of the open class with the abstract keyword in the abstract class.
Example
//open class open class Vehicle { //open non-abstract members open fun start() { println("Vehicle is in start mode.") } open fun stop() { println("Vehicle is in stop mode.") } } //abstract class abstract class FourWheeler : Vehicle() { //abstract functions abstract override fun start() abstract override fun stop() } //Car class inheriting abstract class FourWheeler class Car : FourWheeler() { //implementation of abstract function start override fun start() { println("Car is in drive mode.") } //implementation of abstract function stop override fun stop() { println("Car is in stop mode.") } } fun main(args: Array<String>) { val vehicle = Vehicle() vehicle.start() val car = Car() car.start() }
Output
Vehicle is in start mode. Car is in drive mode.
Creating abstract class reference variable
We cannot create instance of abstract class but we can create reference variable of abstract class.
Example
//abstract class abstract class Vehicle { //abstract functions abstract fun start() abstract fun stop() } //Car class inheriting abstract class Vehicle class Car : Vehicle() { //implementation of abstract function start override fun start() { println("Car is in drive mode.") } //implementation of abstract function stop override fun stop() { println("Car is in stop mode.") } //subclass method fun park() { println("Car is in park mode.") } } fun main(args: Array<String>) { //error:'Vehicle' is abstract; cannot be instantiated //Vehicle vehicle = new Vehicle(); // We can have references of abstract class type. val car: Vehicle = Car() car.start() car.stop() //error: using base class reference variable we can only access its own members. //car.park() //park is not a function of Vehicle abstract class. }
Output
Car is in drive mode. Car is in stop mode.
Note: Using abstract class reference variable we cannot access subclass members.
Abstract class Constructor
An abstract class can contain constructors and it is called when an instance of inherited class is created.
Example
//abstract class primary constructor with initializer block abstract class Employee(name: String, age: Int) { init { println("My name is $name, $age years old ") } } //subclass inheriting abstract class Employee //subclass primary constructor with initializer block class Manager(name: String, age: Int, salary: Int) : Employee(name, age) { init { println("I am Manager and earning $salary per month.") println() } } fun main(args: Array<String>) { //creating subclass instance Manager("Arun", 40, 90000) }
Output
My name is Arun, 40 years old I am Manager and earning 90000 per month.
Example
//abstract class abstract class Employee { //abstract class secondary constructor constructor(name: String, age: Int) { println("My name is $name, $age years old ") } } //subclass inheriting abstract class class Manager : Employee { //secondary constructor calling abstract class secondary constructor constructor(name: String, age: Int, salary: Int) : super(name, age) { println("I am Manager and earning $salary per month.") println() } } fun main(args: Array<String>) { //creating subclass instance Manager("Arun", 40, 90000) }
Output
My name is Arun, 40 years old I am Manager and earning 90000 per month.
Visit Kotlin Constructor in Inheritance to learn more about Constructor behavior in Inheritance.
Points to Remember:
- To create abstract classes and abstract members we use the abstract keyword.
- Abstract methods have no implementation (method body) and abstract properties are not initialized.
- A class containing abstract member (abstract property or abstract function ) must be declared as abstract.
- An abstract class can contain abstract and non-abstract methods.
- Abstract classes cannot be instantiated but we can create reference variable of abstract class.
- Abstract class can have constructors.
- The class inheriting the abstract class must either be declared abstract or implement abstract members.
- To create an object of a class that extends abstract class we must have to implement its abstract members in our class.
- If the class inheriting the abstract class is declared abstract, it’s not mandatory to override abstract methods but now we cannot create an instance of subclass.