Introduction
In this section, we will explore two fundamental concepts of Object-Oriented Programming (OOP) in Kotlin: inheritance and interfaces. These concepts allow you to create more modular, reusable, and maintainable code.
Inheritance
What is Inheritance?
Inheritance is a mechanism in OOP that allows a new class (derived class) to inherit properties and methods from an existing class (base class). This promotes code reuse and establishes a natural hierarchy between classes.
Syntax
In Kotlin, inheritance is declared using the open keyword for the base class and the : symbol for the derived class.
open class Animal {
fun eat() {
println("Eating...")
}
}
class Dog : Animal() {
fun bark() {
println("Barking...")
}
}
fun main() {
val dog = Dog()
dog.eat() // Inherited method
dog.bark() // Own method
}Explanation
open class Animal: Theopenkeyword allows the class to be inherited.class Dog : Animal(): TheDogclass inherits from theAnimalclass.dog.eat(): TheDogclass can use theeatmethod from theAnimalclass.
Practical Example
Let's create a more detailed example with a base class Vehicle and a derived class Car.
open class Vehicle(val name: String, val speed: Int) {
open fun displayInfo() {
println("Vehicle Name: $name, Speed: $speed")
}
}
class Car(name: String, speed: Int, val fuelType: String) : Vehicle(name, speed) {
override fun displayInfo() {
super.displayInfo()
println("Fuel Type: $fuelType")
}
}
fun main() {
val car = Car("Toyota", 120, "Petrol")
car.displayInfo()
}Explanation
open fun displayInfo(): Theopenkeyword allows the method to be overridden.override fun displayInfo(): TheCarclass overrides thedisplayInfomethod to add more information.
Interfaces
What is an Interface?
An interface in Kotlin is a blueprint of a class that contains abstract methods and properties. A class can implement multiple interfaces, providing a way to achieve multiple inheritance.
Syntax
Interfaces are declared using the interface keyword.
interface Drivable {
fun drive()
}
class Bicycle : Drivable {
override fun drive() {
println("Driving a bicycle")
}
}
fun main() {
val bicycle = Bicycle()
bicycle.drive()
}Explanation
interface Drivable: Declares an interface with an abstract methoddrive.class Bicycle : Drivable: TheBicycleclass implements theDrivableinterface.override fun drive(): TheBicycleclass provides an implementation for thedrivemethod.
Practical Example
Let's create an interface Flyable and a class Airplane that implements it.
interface Flyable {
fun fly()
}
class Airplane(val model: String) : Flyable {
override fun fly() {
println("$model is flying")
}
}
fun main() {
val airplane = Airplane("Boeing 747")
airplane.fly()
}Explanation
interface Flyable: Declares an interface with an abstract methodfly.class Airplane : Flyable: TheAirplaneclass implements theFlyableinterface.override fun fly(): TheAirplaneclass provides an implementation for theflymethod.
Combining Inheritance and Interfaces
Example
Let's create a class FlyingCar that inherits from Vehicle and implements Flyable.
interface Flyable {
fun fly()
}
open class Vehicle(val name: String, val speed: Int) {
open fun displayInfo() {
println("Vehicle Name: $name, Speed: $speed")
}
}
class FlyingCar(name: String, speed: Int, val fuelType: String) : Vehicle(name, speed), Flyable {
override fun displayInfo() {
super.displayInfo()
println("Fuel Type: $fuelType")
}
override fun fly() {
println("$name is flying at speed $speed")
}
}
fun main() {
val flyingCar = FlyingCar("SkyCar", 200, "Electric")
flyingCar.displayInfo()
flyingCar.fly()
}Explanation
class FlyingCar : Vehicle, Flyable: TheFlyingCarclass inherits fromVehicleand implementsFlyable.override fun fly(): TheFlyingCarclass provides an implementation for theflymethod.
Exercises
Exercise 1
Create a base class Person with properties name and age, and a method displayInfo. Then, create a derived class Student that adds a property studentId and overrides the displayInfo method to include the studentId.
Solution
open class Person(val name: String, val age: Int) {
open fun displayInfo() {
println("Name: $name, Age: $age")
}
}
class Student(name: String, age: Int, val studentId: String) : Person(name, age) {
override fun displayInfo() {
super.displayInfo()
println("Student ID: $studentId")
}
}
fun main() {
val student = Student("Alice", 20, "S12345")
student.displayInfo()
}Exercise 2
Create an interface Playable with a method play. Then, create a class Guitar that implements Playable and provides an implementation for the play method.
Solution
interface Playable {
fun play()
}
class Guitar : Playable {
override fun play() {
println("Playing the guitar")
}
}
fun main() {
val guitar = Guitar()
guitar.play()
}Conclusion
In this section, we covered the concepts of inheritance and interfaces in Kotlin. We learned how to create base and derived classes, override methods, and implement interfaces. These concepts are fundamental for building modular and reusable code in Kotlin. In the next section, we will explore visibility modifiers to control access to class members.
Kotlin Programming Course
Module 1: Introduction to Kotlin
- Introduction to Kotlin
- Setting Up the Development Environment
- Kotlin Basics: Variables and Data Types
- Control Flow: Conditionals and Loops
- Functions and Lambdas
Module 2: Object-Oriented Programming in Kotlin
- Classes and Objects
- Inheritance and Interfaces
- Visibility Modifiers
- Data Classes and Sealed Classes
- Object Declarations and Companion Objects
Module 3: Advanced Kotlin Features
- Collections and Generics
- Extension Functions
- Higher-Order Functions and Functional Programming
- Coroutines and Asynchronous Programming
- DSL (Domain Specific Language) in Kotlin
Module 4: Kotlin for Android Development
- Introduction to Android Development with Kotlin
- Building User Interfaces
- Handling User Input
- Networking and Data Storage
- Testing and Debugging
