Skip to main content

Overview

Inheritance allows contracts to inherit properties and functions from parent contracts, enabling code reuse and creating hierarchical contract relationships.

Basic Inheritance

Use the is keyword to inherit from a parent contract:
AddFiveStorage.sol
import {SimpleStorage} from "./SimpleStorage.sol";

contract AddFiveStorage is SimpleStorage {
    // Inherits all functions and state variables from SimpleStorage
}
The child contract (AddFiveStorage) automatically has access to all public and internal functions and state variables from the parent contract (SimpleStorage).

Function Overriding

Child contracts can override parent functions to change their behavior.

Requirements for Overriding

  1. Parent function must be marked as virtual
  2. Child function must use the override keyword

Parent Contract

First, mark the function as virtual in the parent:
SimpleStorage.sol
contract SimpleStorage {
    uint256 myFavoriteNumber = 3;

    function store(uint256 _favoriteNumber) public virtual {
        myFavoriteNumber = _favoriteNumber;
    }
}

Child Contract

Then override it in the child:
AddFiveStorage.sol
contract AddFiveStorage is SimpleStorage {
    function store(uint256 _favoriteNumber) public override {
        myFavoriteNumber = _favoriteNumber + 5;
    }
}
The override keyword explicitly declares that this function is meant to override a parent function. This prevents accidental naming conflicts.

How It Works

contract SimpleStorage {
    uint256 myFavoriteNumber = 3;

    function store(uint256 _favoriteNumber) public virtual {
        myFavoriteNumber = _favoriteNumber;
    }

    function retrieve() public view returns (uint256) {
        return myFavoriteNumber;
    }
}
Calling store(10) sets myFavoriteNumber to 10.

Accessing Parent Functions

You can call the parent’s version of an overridden function using super:
contract AddFiveStorage is SimpleStorage {
    function store(uint256 _favoriteNumber) public override {
        // Call parent's store function first
        super.store(_favoriteNumber);
        // Then add 5
        myFavoriteNumber += 5;
    }
}

Multiple Inheritance

Solidity supports multiple inheritance. Contracts can inherit from multiple parents:
contract A {
    function foo() public virtual returns (string memory) {
        return "A";
    }
}

contract B {
    function bar() public virtual returns (string memory) {
        return "B";
    }
}

contract C is A, B {
    // Inherits both foo() and bar()
}
When using multiple inheritance, be aware of the C3 linearization order. Always list parent contracts from “most base-like” to “most derived”.

Constructor Inheritance

If the parent contract has a constructor with parameters, the child must pass them:
contract Parent {
    address public owner;
    
    constructor(address _owner) {
        owner = _owner;
    }
}

contract Child is Parent {
    constructor(address _owner) Parent(_owner) {
        // Child-specific initialization
    }
}

Visibility and Inheritance

VisibilityInherited by ChildAccessible from Outside
publicYesYes
internalYesNo
privateNoNo
externalNo*Yes
*External functions can be called via this.functionName() but are not directly inherited.

When to Use Inheritance

Good Use Cases

  • Creating specialized versions of a contract
  • Implementing standard interfaces (ERC20, ERC721)
  • Sharing common functionality across multiple contracts
  • Building modular, upgradeable systems

Example: Factory Pattern

StorageFactory.sol
contract StorageFactory {
    function createAddFiveStorage() public {
        AddFiveStorage newContract = new AddFiveStorage();
        // newContract behaves like SimpleStorage but adds 5
    }
}

Complete Example

Here’s the full working example:
SimpleStorage.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

contract SimpleStorage {
    uint256 myFavoriteNumber = 3;

    function store(uint256 _favoriteNumber) public virtual {
        myFavoriteNumber = _favoriteNumber;
    }

    function retrieve() public view returns (uint256) {
        return myFavoriteNumber;
    }
}
AddFiveStorage.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

import {SimpleStorage} from "./SimpleStorage.sol";

contract AddFiveStorage is SimpleStorage {
    function store(uint256 _favoriteNumber) public override {
        myFavoriteNumber = _favoriteNumber + 5;
    }
}

Key Takeaways

  • Use is keyword to inherit from parent contracts
  • Parent functions need virtual to be overrideable
  • Child functions need override to override parent functions
  • Child contracts inherit all public/internal state variables and functions
  • Use super to call parent implementations
  • Inheritance enables code reuse and polymorphism in Solidity

Build docs developers (and LLMs) love