Lesson 11 of 25
Inheritance
Extend contracts with the is keyword, override functions, and call super.
IntermediateBasic Inheritance
Solidity supports single and multiple inheritance using the
is keyword. Child contracts inherit all non-private state variables and functions from their parents.
Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Animal {
string public name;
constructor(string memory _name) {
name = _name;
}
function speak() public virtual returns (string memory) {
return "...";
}
}
contract Dog is Animal {
constructor(string memory _name) Animal(_name) {}
// Override parent function with `override` keyword
function speak() public pure override returns (string memory) {
return "Woof!";
}
}
Multiple Inheritance & Linearization
Solidity resolves multiple inheritance using C3 linearization. List base contracts from most-base to most-derived to avoid ambiguity.
Solidity
contract Ownable {
address public owner;
constructor() { owner = msg.sender; }
modifier onlyOwner() {
require(msg.sender == owner, "Not owner");
_;
}
}
contract Pausable {
bool public paused;
modifier whenNotPaused() {
require(!paused, "Paused");
_;
}
function pause() internal { paused = true; }
}
// Inherits from both — list most-base first
contract MyToken is Ownable, Pausable {
function transfer(address to, uint256 amount)
public whenNotPaused
{
// transfer logic
}
function emergencyPause() public onlyOwner {
pause();
}
}
Calling super
Use
super to call the parent's implementation. Essential when overriding to preserve parent logic.
Solidity
contract Base {
event Log(string msg);
function foo() public virtual {
emit Log("Base.foo");
}
}
contract Middle is Base {
function foo() public virtual override {
emit Log("Middle.foo");
super.foo(); // calls Base.foo
}
}
contract Child is Middle {
function foo() public override {
emit Log("Child.foo");
super.foo(); // calls Middle.foo (which calls Base.foo)
// Events emitted: "Child.foo", "Middle.foo", "Base.foo"
}
}