Welcome back! Now that you have a solid understanding of classes and objects, it's time to build on that knowledge by exploring inheritance. Consider it a natural progression in our journey into object-oriented programming (OOP).
Inheritance allows you to create a new class based on an existing class. By using inheritance, you can reuse code, add new features, and make your programs easier to manage and understand. Let's dive in and see what it's all about.
In this lesson, you'll understand how to use inheritance in Kotlin. We'll cover:
- What Inheritance Is
- How to Implement Inheritance in Kotlin
- Why Inheritance Is Beneficial
You'll also learn about chaining inheritance and how to manage multiple inheritance using interfaces.
Inheritance is a way to establish a relationship between a new class (derived class) and an existing class (base class). The derived class inherits properties and behaviors (methods) from the base class. To better understand this concept, we'll use an example involving a Person
class as the base class and a Student
class as the derived class. This example will help demonstrate how properties and methods are inherited from the base class and how additional features can be added to the derived class.
Let’s start by defining a Person
class, which will act as the base class in our example:
Kotlin1// Define the base class Person with name and age attributes 2open class Person(private val name: String, private val age: Int) { 3 4 // Display function to show name and age 5 fun display() { 6 println("Name: $name, Age: $age") 7 } 8}
In this snippet, the Person
class is defined with private properties name
and age
using a primary constructor. It also includes a display
method to print the details. The open
keyword allows this class to be inherited.
Now, let’s create a Student
class that inherits from the Person
class:
Kotlin1// Define the derived class Student, inheriting from Person 2class Student(name: String, age: Int, private val major: String) : Person(name, age) { 3 4 // Function to display major of the student 5 fun displayMajor() { 6 println("Major: $major") 7 } 8}
In the Student
class, we use :
to inherit from Person
. The Student
class reuses the name
and age
properties from the Person
class, and it adds a new property, major
. The super
call to initialize inherited properties is implicit in Kotlin primary constructors.
Finally, let’s see how we can use these classes in a main
function:
Kotlin1fun main() { 2 // Create a Student object and display its details 3 val student = Student("Bob", 25, "Computer Science") 4 student.display() // Calls the display method from Person class 5 student.displayMajor() // Calls the displayMajor method from Student class 6}
In the main
function, we create an instance of Student
and use it to call methods from both the Person
class (inherited) and the Student
class (specific to Student
).
In this section, we’ll explore some important aspects and limitations of inheritance in Kotlin that you should be aware of when designing your class hierarchies.
-
Chaining Inheritance: In Kotlin, you can create a chain of inheritance where a class inherits from another class, which in turn can be inherited by yet another class. This allows you to build complex class hierarchies where each class extends the functionality of the previous one.
-
Single Inheritance with Classes: Kotlin supports single inheritance, meaning a class can only inherit from one superclass. This is similar to Java and helps to keep the class hierarchy simple and avoid ambiguity.
-
Multiple Inheritance via Interfaces: Kotlin allows a class to implement multiple interfaces. This approach provides the flexibility of multiple inheritance, enabling a class to inherit behavior from multiple sources.
-
Open and Final Classes: By default, classes in Kotlin are
final
, meaning they cannot be inherited. Using theopen
keyword allows a class to be extended. This helps to avoid unintentional inheritance issues, making class design more intentional.
Understanding these specifications of inheritance in Kotlin helps you design effective and maintainable object-oriented systems.
Inheritance is powerful for several reasons:
- Code Reusability: Instead of rewriting common functionalities, you can inherit them from a base class, making maintenance easier and reducing errors.
- Extension: You can extend existing code by adding new features to a derived class without changing the existing base class.
- Hierarchy: It helps in organizing code in a hierarchical manner, which reflects real-world relationships and improves code readability and structure.
Inheritance is a cornerstone of OOP, and understanding it will enable you to design more flexible and scalable applications. It's an essential concept for mastering OOP.
In the next unit, we'll also explore how the concept of inheritance enables (runtime) polymorphism, allowing objects of different classes to be treated as objects of a common base class.
Excited to start practicing? Let's move on and put this theory into action!