You put the virtual
keyword in a function when you are happy for an inheriting contract to override the functionality of a particular function, assuming a child contract will use the same function as the parent.
If you explicitly donât want a child contract to potentially overwrite the functionality of a function, then you should not include the virtual
word on a function.
You should put override
on a function when you want this particular function to override the functionality of another virtual function in another child contract. In this case, the virtual
function will inherit from the override
function.
If the inheriting function inherits an override
function from the parent contract, but it does not include the virtual
keyword, it will not inherit functionality from the parent contract.
A function can have both the virtual
and override
keywords on it when it requires that it will inherit some function from a parent contract, and also provide inheritance to a different child contract.
A common example of this is if you were to inherit from the OpenZeppelin ERC20.sol file and decide to make your own transfer
function. You could write a transfer function which is virtual
by inheriting from the ERC20.sol file, and also and override
function if it expects functions to not be modified if they inherit from your contract.