9. Inheritance in Kotlin
Page 9 | Listen in audio
Inheritance is a fundamental concept in object-oriented programming (OOP) that allows a class to inherit properties and functions from another class. In Kotlin, inheritance is a powerful feature that enhances code reusability and design flexibility. This concept is particularly useful in Android app development, where you often need to create classes that share common behaviors or attributes.
In Kotlin, all classes are final by default, meaning they cannot be inherited. To allow a class to be inherited, you must explicitly mark it as open
. This is a safety feature that prevents accidental inheritance and encourages composition over inheritance where appropriate.
Let's delve into the details of how inheritance works in Kotlin, and how you can leverage it in your Android app development projects.
Defining a Base Class
To create a class that can be inherited, you must declare it with the open
keyword. This signals that the class is designed to be a base class. Here's an example:
open class Vehicle(val make: String, val model: String) {
open fun displayInfo() {
println("Vehicle Make: $make, Model: $model")
}
}
In this example, Vehicle
is a base class with a constructor that takes two parameters, make
and model
. It also includes an open
function displayInfo()
that can be overridden by subclasses.
Creating a Subclass
To create a subclass that inherits from a base class, you use the :
symbol followed by the base class name. You must call the constructor of the base class from the subclass constructor. Here's how you can create a subclass that inherits from Vehicle
:
class Car(make: String, model: String, val numDoors: Int) : Vehicle(make, model) {
override fun displayInfo() {
println("Car Make: $make, Model: $model, Number of Doors: $numDoors")
}
}
In this example, Car
is a subclass of Vehicle
. It adds a new property numDoors
and overrides the displayInfo()
method to include this additional information.
Overriding Methods
In Kotlin, you can override a method from a base class in a subclass by using the override
keyword. This is a crucial feature that allows subclasses to provide specific implementations for methods defined in their base classes.
In the Car
class example, the displayInfo()
method is overridden to display the number of doors in addition to the make and model. This demonstrates how subclasses can extend or modify the behavior of base class methods.
Using Superclass Methods and Properties
Within a subclass, you can access properties and methods of the superclass using the super
keyword. This is useful when you want to call a method from the base class that has been overridden in the subclass. Here's an example:
class Truck(make: String, model: String, val payloadCapacity: Int) : Vehicle(make, model) {
override fun displayInfo() {
super.displayInfo()
println("Payload Capacity: $payloadCapacity kg")
}
}
In this example, the Truck
class overrides the displayInfo()
method but still calls the base class's displayInfo()
method using super.displayInfo()
. This allows the Truck
class to extend the functionality of the Vehicle
class while maintaining the original behavior.
Inheritance and Constructors
When working with inheritance in Kotlin, it's important to understand how constructors are handled. The primary constructor of a subclass must initialize the base class using the primary constructor of the base class. This ensures that all properties of the base class are properly initialized.
If the base class has a secondary constructor, the subclass can choose to call it, but this is less common in practice. In most cases, the primary constructor is used for initialization.
Abstract Classes and Methods
Kotlin also supports abstract classes and methods, which are designed to be inherited but not instantiated directly. An abstract class is declared using the abstract
keyword, and it can contain abstract methods that must be implemented by subclasses.
abstract class Appliance(val brand: String) {
abstract fun turnOn()
fun showBrand() {
println("Brand: $brand")
}
}
In this example, Appliance
is an abstract class with an abstract method turnOn()
and a concrete method showBrand()
. Subclasses of Appliance
must provide an implementation for turnOn()
.
Implementing Abstract Methods
When you inherit from an abstract class, you must implement all its abstract methods. Here's an example of how to implement the turnOn()
method in a subclass:
class WashingMachine(brand: String) : Appliance(brand) {
override fun turnOn() {
println("Washing Machine is now ON.")
}
}
In this example, WashingMachine
inherits from Appliance
and provides an implementation for the turnOn()
method. This allows you to create specific types of appliances with their own behavior.
Sealed Classes
In addition to open and abstract classes, Kotlin introduces sealed classes, which are used to represent restricted class hierarchies. A sealed class can have subclasses, but all of them must be declared in the same file. This is useful for representing a fixed set of types.
sealed class Result {
class Success(val data: String) : Result()
class Error(val error: String) : Result()
}
Sealed classes are particularly useful in scenarios where you need to handle a limited set of possible outcomes, such as success or error states in network operations.
Practical Applications in Android Development
Inheritance is widely used in Android app development to create reusable components and enforce consistent behavior across the application. For instance, you might create a base activity class that handles common setup tasks like initializing a toolbar or managing lifecycle events. Subclasses can then inherit from this base activity to implement specific functionality.
Another common use case is creating custom views. You can create a base custom view class that handles common drawing or interaction logic, and then extend it to create more specialized views for different parts of your app.
Conclusion
Inheritance in Kotlin is a powerful tool that allows you to create flexible and reusable code structures. By understanding how to define base classes, create subclasses, override methods, and implement abstract classes, you can design robust Android applications that are easy to maintain and extend. Whether you're building simple apps or complex systems, mastering inheritance will greatly enhance your ability to create effective and efficient software solutions.
Now answer the exercise about the content:
What keyword must be used in Kotlin to allow a class to be inherited?
You are right! Congratulations, now go to the next page
You missed! Try again.
Next page of the Free Ebook: