Bird
Raised Fist0
Blockchain / Solidityprogramming~10 mins

Virtual and override keywords in Blockchain / Solidity - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Virtual and override keywords
Define base function
↓
Mark function as virtual
↓
Create derived contract
↓
Override base function
↓
Use override keyword
↓
Call function via base or derived
↓
Derived function runs if overridden
Shows how a base function marked virtual can be replaced by a derived function using override, enabling dynamic behavior.
Execution Sample
Blockchain / Solidity
contract Base {
  function greet() public virtual returns (string memory) {
    return "Hello from Base";
  }
}

contract Derived is Base {
  function greet() public override returns (string memory) {
    return "Hello from Derived";
  }
}
Defines a base contract with a virtual function and a derived contract that overrides it.
Execution Table
StepActionFunction CalledResultNotes
1Call greet() on Base instanceBase.greet()"Hello from Base"Base function runs as is
2Call greet() on Derived instanceDerived.greet()"Hello from Derived"Derived override runs
3Call greet() via Base reference to DerivedDerived.greet()"Hello from Derived"Override used due to virtual
4Remove override keyword in DerivedCompile errorErrorMust use override to replace virtual function
💡 Execution stops after demonstrating override behavior and compile error on missing override
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3Final
Function greet()Base versionBase versionDerived versionDerived versionDerived version
Key Moments - 3 Insights
Why do we need the virtual keyword in the base contract?
The virtual keyword (see Step 1 in execution_table) tells the compiler the function can be replaced in derived contracts. Without it, override is not allowed.
What happens if we forget the override keyword in the derived contract?
As shown in Step 4, the compiler gives an error because override explicitly confirms you intend to replace a virtual function.
When calling greet() via a base contract reference to a derived instance, which function runs?
Step 3 shows the derived override runs because the base function is virtual, enabling dynamic dispatch.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the output when calling greet() on a Base instance?
ACompile error
B"Hello from Base"
C"Hello from Derived"
DEmpty string
💡 Hint
Check Step 1 in the execution_table for the Base instance call result.
At which step does the compiler error occur if override keyword is missing?
AStep 2
BStep 3
CStep 4
DNo error
💡 Hint
See Step 4 in execution_table where missing override causes compile error.
If the base function is not marked virtual, what happens when derived tries to override?
ACompile error
BDerived function runs anyway
CBase function runs always
DRuntime error
💡 Hint
Refer to key_moments about the need for virtual keyword to allow override.
Concept Snapshot
virtual keyword marks a base function as replaceable
override keyword confirms replacement in derived contract
Calling via base uses derived function if overridden
Missing override causes compile error
No virtual means no override allowed
Full Transcript
This example shows how in blockchain smart contracts, a base contract can define a function as virtual, meaning it can be replaced by derived contracts. The derived contract uses the override keyword to replace the base function. When calling the function on a derived instance or via a base reference to derived, the overridden function runs. If override is missing, the compiler gives an error. If virtual is missing in base, override is not allowed. This enables flexible and safe function replacement in contract inheritance.

Practice

(1/5)
1. What does the virtual keyword do in a blockchain smart contract?
easy
A. Makes a function private
B. Prevents a function from being changed
C. Deletes a function from the contract
D. Allows a function to be changed in child contracts

Solution

  1. Step 1: Understand the role of virtual

    The virtual keyword marks a function so child contracts can change it.
  2. Step 2: Compare with other options

    Options B, C, and D describe behaviors that virtual does not do.
  3. Final Answer:

    Allows a function to be changed in child contracts -> Option D
  4. Quick Check:

    virtual = allows override [OK]
Hint: Virtual means function can be changed later [OK]
Common Mistakes:
  • Thinking virtual makes function private
  • Confusing virtual with override
  • Believing virtual deletes functions
2. Which of the following is the correct way to override a virtual function named transfer in a child contract?
easy
A. function transfer() public virtual { }
B. function transfer() public override { }
C. function transfer() public final { }
D. function transfer() public abstract { }

Solution

  1. Step 1: Identify override syntax

    To replace a virtual function, use override keyword in the child function.
  2. Step 2: Check options

    function transfer() public override { } uses override, correct for overriding. function transfer() public virtual { } uses virtual which allows override but does not override itself. Options C and D are incorrect keywords here.
  3. Final Answer:

    function transfer() public override { } -> Option B
  4. Quick Check:

    Override keyword replaces virtual function [OK]
Hint: Use override keyword to replace virtual function [OK]
Common Mistakes:
  • Using virtual instead of override to replace function
  • Using final or abstract incorrectly
  • Omitting override keyword
3. Consider this Solidity code snippet:
contract Parent {
    function greet() public virtual returns (string memory) {
        return "Hello from Parent";
    }
}

contract Child is Parent {
    function greet() public override returns (string memory) {
        return "Hello from Child";
    }
}

contract Test {
    function testGreet() public returns (string memory) {
        Child c = new Child();
        return c.greet();
    }
}

What will testGreet() return when called?
medium
A. "Hello from Parent"
B. Compilation error
C. "Hello from Child"
D. Runtime error

Solution

  1. Step 1: Understand virtual and override behavior

    The greet function in Parent is marked virtual, allowing Child to override it.
  2. Step 2: Check which function is called

    When c.greet() is called on a Child instance, the overridden greet in Child runs, returning "Hello from Child".
  3. Final Answer:

    "Hello from Child" -> Option C
  4. Quick Check:

    Override function runs on child instance [OK]
Hint: Child override runs, not parent virtual function [OK]
Common Mistakes:
  • Expecting parent function output
  • Thinking override causes error
  • Confusing virtual with abstract
4. What is wrong with this Solidity code?
contract Base {
    function foo() public virtual returns (string memory) {
        return "Base";
    }
}

contract Derived is Base {
    function foo() public returns (string memory) {
        return "Derived";
    }
}
medium
A. Missing override keyword in Derived's foo function
B. Base's foo function should not be virtual
C. Derived's foo function should be private
D. No errors, code is correct

Solution

  1. Step 1: Check override rules

    Since foo in Base is virtual, the overriding function in Derived must use override keyword.
  2. Step 2: Identify missing keyword

    The foo function in Derived lacks override, causing a compilation error.
  3. Final Answer:

    Missing override keyword in Derived's foo function -> Option A
  4. Quick Check:

    Override keyword required when replacing virtual function [OK]
Hint: Override keyword is mandatory when replacing virtual functions [OK]
Common Mistakes:
  • Forgetting override keyword
  • Thinking virtual is optional in base
  • Making function private incorrectly
5. You have a contract hierarchy:
contract A {
    function calc() public virtual returns (uint) {
        return 1;
    }
}

contract B is A {
    function calc() public virtual override returns (uint) {
        return 2;
    }
}

contract C is B {
    function calc() public override returns (uint) {
        return 3;
    }
}

If you call calc() on a C contract instance, what is the output and why?
hard
A. 3, because C overrides B's function
B. 1, because A's function is virtual
C. 2, because B overrides A and is virtual
D. Compilation error due to multiple overrides

Solution

  1. Step 1: Trace overrides in inheritance

    Contract A defines calc as virtual. B overrides it and keeps it virtual. C overrides B's version without virtual.
  2. Step 2: Determine which function runs on C instance

    Calling calc() on C runs C's override, returning 3.
  3. Final Answer:

    3, because C overrides B's function -> Option A
  4. Quick Check:

    Most derived override runs on instance [OK]
Hint: Most derived override runs, even if base is virtual [OK]
Common Mistakes:
  • Thinking base virtual function runs
  • Confusing virtual with override
  • Expecting compilation error from multiple overrides
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard