Swift Inheritance

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,

  1. Car is a Vehicle
  2. Apple is a Fruit
  3. 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.

Did you find this article helpful?