Reusing Code with Inheritance
Inheritance lets one contract build on another, reusing its logic instead of duplicating it. A derived contract declares contract Child is Parent, and immediately gains the parent's non-private state variables and functions. This underpins nearly every real-world Solidity project — access-control mixins like Ownable, token bases like ERC20, and reentrancy guards are all inherited. Inheritance keeps contracts DRY and lets audited base contracts, such as OpenZeppelin's, provide battle-tested behavior you extend rather than reimplement.
Cricket analogy: Inheritance is like an academy player inheriting the club's training drills and kit, then adding their own shots — a derived contract gets the base's functions plus its own.
virtual, override, and super
To let a derived contract replace a function, the base must mark it virtual, and the derived version must be marked override. Inside the override you can call the parent's implementation with super.functionName(...), which invokes the next contract in the inheritance chain rather than any one specific parent. This is how you wrap base behavior — for example, adding a zero-address check before delegating to super.transferOwnership(to). A function that is itself overridden further down the chain must be both override and virtual.
Cricket analogy: A base method marked virtual is like a coaching drill flagged 'customizable' — a player can override it with their own technique, and super lets them still run the original drill first.
contract Ownable {
address public owner = msg.sender;
function transferOwnership(address to) public virtual {
owner = to;
}
}
contract Restricted is Ownable {
function transferOwnership(address to) public override {
require(to != address(0), "zero address");
super.transferOwnership(to); // run the parent implementation
}
}Only functions marked virtual can be overridden, and state variables can never be overridden. A public state variable auto-generates a getter, but to change behavior a derived contract must override an explicit function, not the variable itself.
Multiple Inheritance and C3 Linearization
Solidity supports inheriting from several contracts at once, and resolves the resulting graph using C3 linearization — the same algorithm Python uses. You must list base contracts from most-base to most-derived, and the linearization determines the order in which overrides and super calls are dispatched. When two parents define the same function, the override must name all of them, as in override(A, B). This deterministic ordering is how Solidity tames the classic 'diamond problem' of multiple inheritance.
Cricket analogy: Multiple inheritance is a player learning from both a batting coach and a fielding coach; C3 linearization fixes a strict order so overlapping advice resolves predictably, most-base coach last.
In multiple inheritance, listing base contracts in the wrong order breaks C3 linearization and fails to compile. When two parents define the same function, the override must explicitly name every base it overrides, e.g. override(A, B), or the compiler rejects it.
Constructor Chaining
When a contract is deployed, base constructors run before the derived constructor, in linearization order, so a contract is never used before its foundations are set up. You pass arguments to a base constructor either in the inheritance list (contract C is Base(1)) or, when the value is computed, in the derived constructor's modifier list (constructor(uint x) Base(x * 2) {}). Getting this chain right ensures every inherited state variable is initialized exactly once, in a predictable sequence, before the contract goes live.
Cricket analogy: Constructor chaining is like a new signing being kitted out by the academy before the senior team adds their gear — base constructors run first, in linearization order, then the derived one.
contract A {
constructor(uint n) { /* init A */ }
}
contract B {
constructor(uint n) { /* init B */ }
}
// Bases run in linearization order, not the order of arguments
contract C is A, B {
constructor() A(1) B(2) {}
}- A contract inherits another with the is keyword, gaining its non-private functions and state variables.
- A base function must be marked virtual to be overridable, and the overriding function must use override.
- super calls the next implementation in the C3-linearized inheritance chain, not one fixed parent.
- Solidity supports multiple inheritance and resolves it with C3 linearization; bases are listed most-base first.
- An override that replaces several parents must name them all, e.g. override(A, B).
- Base constructors execute before the derived constructor, in linearization order, receiving arguments via the inheritance or modifier list.
- State variables cannot be overridden, and private functions are not visible to derived contracts.
Practice what you learned
1. Which keyword must a base function have to allow a derived contract to override it?
2. What does super.foo() call?
3. In what order do constructors run in an inheritance hierarchy?
4. How does Solidity resolve conflicts in multiple inheritance?
5. When overriding a function defined in two parents A and B, what must the override specify?
Was this page helpful?
You May Also Like
Interfaces and Abstract Contracts
Interfaces declare pure behavior for interoperability, while abstract contracts provide partial, shareable implementation — together they let you program to a contract's behavior, not its source.
Access Control Patterns
Techniques for restricting who can call privileged contract functions, from simple Ownable to role-based access control, safe ownership transfer, and timelocks.
Structs and Enums in Solidity
Structs group related fields into custom record types, while enums give readable names to a fixed set of states — together they turn loose primitives into safe, self-documenting data models.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics