DEV Community

Jamiebones
Jamiebones

Posted on

Inheritance In Solidity (My Web3 Journey ) part 5

Solidity supports object oriented programming paradigm of inheritance. Inheritance means adding extra functionality to a contract by inheriting them from another contract.

We could want some functionality in our contract and instead of defining and implementing them from scratch, we could just inherit it from a base or parent contract.

Inheritance of a contract in solidity is done by the is keyword. Solidity supports multiple inheritance; meaning you can inherit from more than one parent contract.

Inheritance tips

  • Inheritance is done by using the is keyword to inherit from a base contract.

  • A Function in the parent contract that should be overridden by the child contract should be declared as virtual.

  • A child contract that will override the parent function must use the keyword override.

  • Order of inheritance is important.

pragma solidity ^0.8.4;

interface Bonny {
    //we defined an interface to force contract inheriting that interface to implement the methods define n the interface
  function gethelp() external view returns (string memory);
}

contract BaseContract{
  //the key world virtual is used to defined a function that will be overiden by the child contract
  function actWise() public view virtual returns (string memory){
    return "Base is wise";
  }

  function hello() public view returns (string memory){
      return "Hello Motor";
  }
}


contract A is BaseContract {
    function sayHello() public view returns (string memory){
        //we are calling the hello function in the BaseContract
        return hello();
    }
    //we have overridden the base contract actWise function with our own implementationof it
    function actWise() public view virtual override returns (string memory){
        return "Contract A is wise";
    }
}

contract B is BaseContract {

    //we have overriden the base contract actWise function with our own implementationof it
    function actWise() public view virtual override returns (string memory){
        return "Contract B is wise";
    }
}

contract D is A, B, Bonny {
    function actWise() public view override(A,B) returns (string memory){
        //super refers to the parent of the derived contract
        //if the inheritance is multiple super refers to the right most parent. In this case super refers to B
        return super.actWise();
    }

    function gethelp() public view returns (string memory){
        return "help me please!";
    }

}

Enter fullscreen mode Exit fullscreen mode

The example above consist of a base contract named BaseContract. The BaseContract defines two methods named actWise and sayHello.

The function actWise is defined as virtual which means contracts inheriting (derived contracts) it, has an option to declare and execute their own implementation of the function actWise.

This is seen by function A and B which inherits from the BaseContract and implemented their own versions of actWise by using the override keyword.

If you look closely at function actWise in both contract A and B,you will notice that it still contain the virtual keyword. We made it so, so that any contract inheriting from them also have the option of overriding the actWise function.

Looking at contract D you can see that it inherits from both contract A and contract B. There is also a third inheritance from an interface called Bonny.

Before, I progress. What is an interface?
I answer my own question by defining an interface as a set of functions that a contract inheriting it must define and implement.

An interface only defines the function name and signature without implementation. The inheriting contract will not compile if the function defined on the interface is not implemented.

An interface is defined using the interface keyword followed by the name of the interface. The functions defined in an interface must be external without a function body.

An interface cannot have a constructor and it does not make use of any state variable.

Coming back to earth

contract D is A, B, Bonny {
    function actWise() public view override(A,B) returns (string memory){
        //super refers to the parent of the derived contract
        //if the inheritance is multiple super refers to the right most parent. In this case super refers to B
        return super.actWise();
    }

    function gethelp() public view returns (string memory){
        return "help me please!";
    }

}
Enter fullscreen mode Exit fullscreen mode

We actwise function was overridden in both parent contract A and B (remember, we also defined the actWise function in contract A and B as virtual which means we can override it).

In our implementation, we decided to call the parent contract actWise function using the keyword super which means the parent contract. Since contract D has two parents that both have the actWise function; the parent at the most right hand side of the inheritance which is contract B will be called by super.

This example shows that the order of inheritance is important when you have more than one parent contract you are inheriting from.

Take away from the lesson:

  • Solidity supports multiple inheritance
  • Order of inheritance matter
  • An interface is a set of functions that a derived contract must implement
  • Inheritance is used to add extra functionality to our contracts.

Until next time, happy coding....

Top comments (0)