In this section, we introduce inheritance
in Solidity, including simple inheritance, multiple inheritance, and inheritance of modifiers and constructors.
Inheritance
Inheritance is one of the core concepts in object-oriented programming, which can significantly reduce code redundancy. It is a mechanism where you can derive a class from another class for a hierarchy of classes that share a set of attributes and methods. In solidity, smart contracts can be viewed as objects, which support inheritance.
Rules
There are two important keywords for inheritance in Solidity:
-
virtual
: If the functions in the parent contract are expected to be overridden in its child contracts, they should be declared asvirtual
. -
override
:If the functions in the child contract override the functions in its parent contract, they should be declared asoverride
.
Note 1: If a function both overrides and is expected to be overridden, it should be labelled as virtual override
.
Note 2: If a public
state variable is labelled as override
, its getter
function will be overridden. For example:
Simple inheritance
Let's start by writing a simple Grandfather
contract, which contains 1 Log
event and 3 functions: hip()
, pop()
, Grandfather()
, which outputs a string "Grandfather"
.
Let's define another contract called Father
, which inherits the Grandfather
contract. The syntax for inheritance is contract Father is Grandfather
, which is very intuitive. In the Father
contract, we rewrote the functions hip()
and pop()
with the override
keyword, changing their output to "Father"
. We also added a new function called father
, which outputs a string "Father"
.
After deploying the contract, we can see that Father
contract contains 4 functions. The outputs of hip()
and pop()
are successfully rewritten with output "Father"
, while the output of the inherited grandfather()
function is still "Grandfather"
.
Multiple inheritance
A solidity contract can inherit multiple contracts. The rules are:
-
For multiple inheritance, parent contracts should be ordered by seniority, from the highest to the lowest. For example:
contract Son is Grandfather, Father
. A error will be thrown if the order is not correct. -
If a function exists in multiple parent contracts, it must be overridden in the child contract, otherwise an error will occur.
-
When a function exists in multiple parent contracts, you need to put all parent contract names after the
override
keyword. For example:override(Grandfather, Father)
.
Example:
After deploying the contract, we can see that we successfully rewrote the hip()
and pop()
functions in the Son
contract, changing the output to "Son"
. While the Grandfather()
and father()
functions inherited from its parent contracts remain unchanged.
Inheritance of modifiers
Likewise, modifiers in Solidity can be inherited as well. Rules for modifier inheritance are similar to the function inheritance, using the virtual
and override
keywords.
Identifier
contract can directly use the exactDividedBy2And3
modifier because it inherits the Base1
contract. We can also rewrite the modifier in the contract:
Inheritance of constructors
Constructors can also be inherited. Let first consider a parent contract A
with a state variable a
, which is initialized in its constructor:
There are two ways for a child contract to inherit the constructor from its parent A
:
-
Declare the parameters of the parent constructor at inheritance:
-
Declare the parameter of the parent constructor in the constructor of the child contract:
Calling the functions from the parent contracts
There are two ways for a child contract to call the functions of the parent contract:
-
Direct calling:The child contract can directly call the parent's function with
parentContractName.functionName()
. For example: -
super
keyword:The child contract can use thesuper.functionName()
to call the function in the neareast parent contract in the inheritance hierarchy. Solidity inheritance is declared in a right-to-left order: forcontract Son is Grandfather, Father
, theFather
contract is closer than theGrandfather
contract. Thus,super.pop()
in theSon
contract will callFather.pop()
but notGrandfather.pop()
.
Diamond inheritance
In Object-Oriented Programming, diamond inheritance refers to the scenario in which a derived class has two or more base classes.
When using the super
keyword on a diamond inheritance chain, it should be noted that it will call the relevant function of each contract in the inheritance chain, not just the nearest parent contract.
First, we write a base contract called God
. Then we write two contracts Adam
and Eve
inheriting from the God
contract. Lastly, we write another contract people
inheriting from Adam
and Eve
. Each contract has two functions, foo()
and bar()
:
In this example, calling the super.bar()
function in the people
contract will call the Eve
, Adam
, and God
contract's bar()
function, which is different from ordinary multiple inheritance.
Although Eve
and Adam
are both child contracts of the God
parent contract, the God
contract will only be called once in the whole process. This is because Solidity borrows the paradigm from Python, forcing a DAG (directed acyclic graph) composed of base classes to guarantee a specific order based on C3 Linearization. For more information on inheritance and linearization, read the official Solidity docs here.
Verify on Remix
- After deploying example contract in Simple Inheritance session, we can see that the
Father
contract hasGrandfather
functions:


- Modifier inheritance examples:



- Inheritance of constructors:


- Calling the functions from parent contracts:


-
Diamond inheritance:
Summary
In this tutorial, we introduced the basic uses of inheritance in Solidity, including simple inheritance, multiple inheritance, inheritance of modifiers and constructors, and calling functions from parent contracts.