An abstract class is a class that cannot be instantiated directly and is meant to be subclassed by other classes. Abstract classes are declared using the abstract
keyword. They can contain both abstract and non-abstract (concrete) properties and methods. Let’s understand the concept of Abstraction.
Abstraction in Kotlin
Abstraction is one of the key principles of Object-Oriented Programming (OOP) that promotes the idea of hiding the implementation details and exposing only the essential features of an object. In Kotlin, like in many other object-oriented languages, abstraction can be achieved through the use of Abstract classes and Interfaces. Here are real-world examples illustrating abstraction:
Banking System: In a banking system, the concept of an account can be abstracted. You can have an abstract class or interface called Account
with methods like deposit()
, withdraw()
, and getBalance()
. Concrete classes like SavingsAccount
and CheckingAccount
can then provide specific implementations.
Abstract Class In kotlin
abstract classes can have a mix of abstract methods (methods without a body) and non-abstract methods (methods with a body). Abstract methods in an abstract class serve as a contract, and any concrete subclass must provide implementations for these abstract methods. Non-abstract methods can also be included in the abstract class, providing default behavior that can be inherited by the subclasses.
Here are some key points about abstract classes in Kotlin:
Cannot be instantiated:
Abstract classes cannot be instantiated directly. You cannot create objects of an abstract class.Keyword abstract
: Theabstract
keyword is used to declare an abstract class. It indicates that the class cannot be fully instantiated and is meant to be subclassed.Abstract methods:
Abstract classes can have abstract methods, which are methods without a body. Subclasses must provide concrete implementations for these abstract methods.Concrete methods:
Abstract classes can also have concrete methods (methods with a body). Subclasses inherit these methods, and they can choose to override them if needed.Properties:
Abstract classes can have both abstract and non-abstract properties. Abstract properties do not have an initial value and must be overridden by subclasses. non-abstract properties can have initial value in abstract class.Constructor:
Abstract classes can have constructors. Subclasses must invoke the constructor of the abstract class using thesuper
keyword.Single inheritance:
Kotlin supports single-class inheritance, meaning a class can inherit from only one superclass, whether it’s abstract or not.Common structure:
Abstract classes are useful for defining a common structure or base functionality shared among multiple related classes.
Here’s the syntax for declaring an abstract class in Kotlin
abstract class AbstractClassName {
// Abstract properties
// it can not be initialized here
abstract val abstractProperty: DataType
// Abstract methods
abstract fun abstractMethod()
// Non-abstract properties
// it can be initialized here
val nonAbstractProperty: DataType = /* initialization */
// Non-abstract methods (with a body)
fun nonAbstractMethod() {
// Body of the method
}
}
In this syntax:
abstract class
: Theabstract
keyword declares that this is an abstract class.AbstractClassName
: Replace this with the desired name of your abstract class.abstractProperty
: Abstract properties do not have an initial value and must be overridden by subclasses.abstractMethod()
: Abstract methods do not have a body and must be implemented by subclasses.nonAbstractProperty
: Non-abstract properties can have an initial value and do not need to be overridden.nonAbstractMethod()
: Non-abstract methods have a body and provide default behavior. They can be inherited by subclasses as-is or overridden.
Example of an abstract class in Kotlin:
// Abstract class definition
abstract class Animal(val name: String) {
// Abstract property
abstract val sound: String
// Abstract method - it must be implemented by subclass
abstract fun makeSound()
// Non-abstract method // default method
fun sleep() {
println("$name is sleeping")
}
}
// Concrete subclass 1
class Dog(name: String) : Animal(name) {
override val sound: String = "Woof" // overriding abstract property
override fun makeSound() {
println("$name says $sound")
}
}
// Concrete subclass 2
class Cat(name: String) : Animal(name) {
override val sound: String = "Meow"
override fun makeSound() {
println("$name says $sound")
}
}
fun main() {
// Using the abstract class and its subclasses
val dog = Dog("Buddy")
val cat = Cat("Whiskers")
dog.makeSound()
dog.sleep()
cat.makeSound()
cat.sleep()
}
//Output
Buddy says Woof
Buddy is sleeping
Whiskers says Meow
Whiskers is sleeping
In this example:
Animal
is an abstract class with an abstract propertysound
and an abstract methodmakeSound()
.- The abstract class has a non-abstract method
sleep()
with a default implementation. Dog
andCat
are concrete subclasses of theAnimal
abstract class. They provide specific implementations for the abstract property and method.
This example demonstrates how abstract classes can be used to define a common structure for a group of related classes while allowing each subclass to provide its own unique implementation.
what is the use of constructor in abstract class ?
The main purpose of having constructors in an abstract class is to initialize the common properties or provide a mechanism for initializing the state of its subclasses and performing any necessary setup when an instance of a concrete subclass is created..
The constructor of an abstract class can be used to ensure that certain properties are initialized before the abstract methods or non-abstract methods are called.
By having constructors in an abstract class, it can be reused initialization logic by multiple subclasses.
Here’s an example to illustrate the use of a constructor in an abstract class:
abstract class Shape(val name: String) {
init {
println("Initializing $name")
}
abstract fun calculateArea(): Double
fun displayInfo() {
println("$name - Area: ${calculateArea()}")
}
}
class Circle(radius: Double) : Shape("Circle") {
private val radius: Double = radius
override fun calculateArea(): Double {
return Math.PI * radius * radius
}
}
class Square(sideLength: Double) : Shape("Square") {
private val sideLength: Double = sideLength
override fun calculateArea(): Double {
return sideLength * sideLength
}
}
fun main() {
val circle = Circle(5.0)
val square = Square(4.0)
circle.displayInfo()
square.displayInfo()
}
//Output
Initializing Circle
Initializing Square
Circle - Area: 78.53981633974483
Square - Area: 16.0
- The
Shape
abstract class has a constructor that takes aname
parameter. Theinit
block in the constructor is executed when an instance of the concrete subclass is created. - The concrete subclasses
Circle
andSquare
provide their specific implementations for thecalculateArea
method. - When an instance of
Circle
orSquare
is created, the constructor of the abstract class (Shape
) is called, and the initialization block prints a message indicating the type of shape being initialized.
Use cases of abstract classes in Android development:
Activity Lifecycle:
It is used to define a base activity class that encapsulates common behavior and methods related to the Activity lifecycle. Subclasses (individual activities) can then extend this abstract class to inherit and customize the common behavior.Fragment Management:
It is used to create a base fragment class that includes common logic for fragment transactions, lifecycle handling, or UI interactions. Subclasses representing individual fragments can extend this abstract class to reuse common functionality.Adapter Classes:
Abstract classes are useful for creating base adapter classes in Android, such asBaseAdapter
orRecyclerView.Adapter
. Subclasses can extend these abstract adapters to provide custom implementations for adapting data to UI elements.Permission Handling:
Abstract classes can be used to create a base class for handling runtime permissions in Android. Subclasses can extend this abstract class to implement logic for requesting and handling permissions in different parts of the app.
To learn more about Kotlin abstract class, check out the official documentation at: Kotlinlang