Virtual and override keywords help control how functions behave when you change or extend code. They let you change parts of a program safely without breaking it.
Virtual and override keywords in Blockchain / Solidity
contract Base {
function example() public virtual {
// base code
}
}
contract Child is Base {
function example() public override {
// new code
}
}virtual means the function can be changed in child contracts.
override means the function is changing a virtual function from a parent contract.
contract Animal {
function sound() public virtual returns (string memory) {
return "Some sound";
}
}contract Dog is Animal { function sound() public override returns (string memory) { return "Bark"; } }
contract Cat is Animal { function sound() public override returns (string memory) { return "Meow"; } }
This program shows a base contract Vehicle with a virtual function move(). Two contracts, Car and Bike, override move() to give their own messages. The Test contract calls both to show the different results.
pragma solidity ^0.8.0; contract Vehicle { function move() public virtual returns (string memory) { return "Vehicle is moving"; } } contract Car is Vehicle { function move() public override returns (string memory) { return "Car is driving"; } } contract Bike is Vehicle { function move() public override returns (string memory) { return "Bike is pedaling"; } } contract Test { function testMove() public pure returns (string memory, string memory) { Car car = new Car(); Bike bike = new Bike(); return (car.move(), bike.move()); } }
Always mark functions as virtual in the base contract if you want child contracts to change them.
When overriding, you must use the override keyword to avoid mistakes.
If you forget virtual or override, the compiler will give an error to help you fix it.
virtual lets a function be changed in child contracts.
override shows a function is changing a virtual function from a parent.
Using these keywords helps keep your blockchain contracts safe and easy to update.
Practice
virtual keyword do in a blockchain smart contract?Solution
Step 1: Understand the role of
Thevirtualvirtualkeyword marks a function so child contracts can change it.Step 2: Compare with other options
Options B, C, and D describe behaviors thatvirtualdoes not do.Final Answer:
Allows a function to be changed in child contracts -> Option DQuick Check:
virtual= allows override [OK]
- Thinking virtual makes function private
- Confusing virtual with override
- Believing virtual deletes functions
transfer in a child contract?Solution
Step 1: Identify override syntax
To replace a virtual function, useoverridekeyword in the child function.Step 2: Check options
function transfer() public override { } usesoverride, correct for overriding. function transfer() public virtual { } usesvirtualwhich allows override but does not override itself. Options C and D are incorrect keywords here.Final Answer:
function transfer() public override { } -> Option BQuick Check:
Override keyword replaces virtual function [OK]
- Using virtual instead of override to replace function
- Using final or abstract incorrectly
- Omitting override keyword
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?Solution
Step 1: Understand virtual and override behavior
Thegreetfunction inParentis markedvirtual, allowingChildto override it.Step 2: Check which function is called
Whenc.greet()is called on aChildinstance, the overriddengreetinChildruns, returning "Hello from Child".Final Answer:
"Hello from Child" -> Option CQuick Check:
Override function runs on child instance [OK]
- Expecting parent function output
- Thinking override causes error
- Confusing virtual with abstract
contract Base {
function foo() public virtual returns (string memory) {
return "Base";
}
}
contract Derived is Base {
function foo() public returns (string memory) {
return "Derived";
}
}Solution
Step 1: Check override rules
SincefooinBaseisvirtual, the overriding function inDerivedmust useoverridekeyword.Step 2: Identify missing keyword
Thefoofunction inDerivedlacksoverride, causing a compilation error.Final Answer:
Missing override keyword in Derived's foo function -> Option AQuick Check:
Override keyword required when replacing virtual function [OK]
- Forgetting override keyword
- Thinking virtual is optional in base
- Making function private incorrectly
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?Solution
Step 1: Trace overrides in inheritance
Contract A definescalcas virtual. B overrides it and keeps it virtual. C overrides B's version without virtual.Step 2: Determine which function runs on C instance
Callingcalc()on C runs C's override, returning 3.Final Answer:
3, because C overrides B's function -> Option AQuick Check:
Most derived override runs on instance [OK]
- Thinking base virtual function runs
- Confusing virtual with override
- Expecting compilation error from multiple overrides
Ready to prove it?
Pass the test and this pattern moves unknown
