Like other OOP languages, Swift also supports the concept of class inheritance.
Inheritance allows us to create a new class from an existing class.
The new class that is created is known as subclass (child or derived class) and the existing class from which the child class is derived is known as superclass (parent or base class).
Swift Inheritance Syntax
In Swift, we use the colon :
to inherit a class from another class. For example,
// define a superclass
class Animal {
// properties and methods definition
}
// inheritance
class Dog: Animal {
// properties and methods of Animal
// properties and methods of Dog
}
Here, we are inheriting the Dog
subclass from the Animal
superclass.
Example: Swift Inheritance
class Animal {
// properties and method of the parent class
var name: String = ""
func eat() {
print("I can eat")
}
}
// inherit from Animal
class Dog: Animal {
// new method in subclass
func display() {
// access name property of superclass
print("My name is ", name);
}
}
// create an object of the subclass
var labrador = Dog()
// access superclass property and method
labrador.name = "Rohu"
labrador.eat()
// call subclass method
labrador.display()
Output
I can eat My name is Rohu
In the above example, we have derived a subclass Dog from a superclass Animal. Notice the statements,
labrador.name = "Rohu"
labrador.eat()
Here, we are using labrador (object of Dog
) to access name and eat()
of the Animal
class. This is possible because the subclass inherits all properties and methods of the superclass.
Also, we have accessed the name property inside the method of the Dog
class.
is-a relationship
In Swift, inheritance is an is-a relationship. That is, we use inheritance only if there exists an is-a relationship between two classes. For example,
- Car is a Vehicle
- Apple is a Fruit
- Cat is an Animal
Here, Car can inherit from Vehicle, Apple can inherit from Fruit, and so on.
Method Overriding in Swift Inheritance
In the previous example, we see the object of the subclass can access the method of the superclass.
However, what if the same method is present in both the superclass and subclass?
In this case, the method in the subclass overrides the method in the superclass. This concept is known as method overriding in Swift.
We use the override
keyword to tell the compiler that we are overriding a method.
Example: Method Overriding
class Animal {
// method in the superclass
func eat() {
print("I can eat")
}
}
// Dog inherits Animal
class Dog: Animal {
// overriding the eat() method
override func eat() {
print("I eat dog food")
}
}
// create an object of the subclass
var labrador = Dog()
// call the eat() method
labrador.eat()
Output
I eat dog food
In the above example, the same method eat()
is present in both the Dog
class and the Animal
class.
Now, when we call the eat()
method using the object of the Dog
subclass, the method of the Dog
class is called.
This is because the eat()
method of the Dog
subclass overrides the same method of the Animal
superclass. We have used the override
keyword to specify the method is overridden.
override func eat() {
print("I eat dog food")
}
super Keyword in Swift Inheritance
Previously we saw that the same method in the subclass overrides the method in the superclass.
However, if we need to access the superclass method from the subclass, we use the super
keyword. For example,
class Animal {
// create method in superclass
func eat() {
print("I can eat")
}
}
// Dog inherits Animal
class Dog: Animal {
// overriding the eat() method
override func eat() {
// call method of superclass
super.eat()
print("I eat dog food")
}
}
// create an object of the subclass
var labrador = Dog()
// call the eat() method
labrador.eat()
Output
I can eat I eat dog food
In the above example, the eat()
method of the Dog
subclass overrides the same method of the Animal
superclass.
Inside the Dog class, we have used
// call method of superclass
super.eat()
to call the eat()
method of the Animal superclass from the Dog subclass.
So, when we call the eat()
method using the labrador
object
// call the eat() method
labrador.eat()
Both the overridden and the superclass version of the eat()
method is executed.
Why Inheritance?
To understand the benefits of Inheritance, let's consider a situation.
Suppose we are working with regular polygons such as squares, pentagons, and so on. And, we have to find the perimeter of these polygons based on the input.
1. Since the formula to calculate perimeter is common for all regular polygons, we can create a Polygon
class and a method calculatePerimeter()
to calculate perimeter.
class RegularPolygon {
calculatePerimeter() {
// code to compute perimeter
}
}
2. And inherit Square
and Pentagon
classes from the RegularPolygon
class. Each of these classes will have properties to store the length and number of sides because they are different for all polygons.
class Square: RegularPolygon {
var length = 0
var sides = 0
}
We pass the value of the length
and sides
to calculatePerimeter()
to compute the perimeter.
This is how inheritance makes our code reusable and more intuitive.
Example: Benefits of Inheritance
import Foundation
class RegularPolygon {
func calculatePerimeter(length: Int, sides: Int) {
var result = length * sides
print("Perimeter:", result )
}
}
// inherit Square from Polygon
class RegularSquare: RegularPolygon {
var length = 0
var sides = 0
func calculateArea() {
var area = length * length
print("Regular Square Area:", area)
}
}
// inherit Pentagon from Polygon
class RegularTriangle: RegularPolygon {
var length = 0.0
var sides = 0.0
func calculateArea() {
var area = (sqrt(3)/4) * (length * length)
print("Regular Triangle Area:", area)
}
}
var shape = RegularSquare()
shape.length = 4
shape.calculateArea()
shape.calculatePerimeter(length: 3,sides:4)
var shape2 = RegularTriangle()
shape2.length = 2
shape2.calculateArea()
shape2.calculatePerimeter(length: 2,sides:3)
Output
Regular Square Area: 16 Perimeter: 12 Regular Triangle Area: 1.7320508075688772 Perimeter: 6
In the above example, we have created a RegularPolygon
class that calculates the perimeter of the regular polygon.
Here, the RegularSquare
and RegularTriangle
inherits from RegularPolygon
.
The formula to calculate the parameter of a regular polygon is common for all, so we have reused the calculatePerimeter()
method of the superclass.
And since the formula to calculate the area is different for different shapes, we have created a separate method inside the subclass to calculate the area.