Search code examples
soliditysmartcontracts

What is the usage of override in Solidity?


I still don't understand the usage of override in solidity. I know the how to write code of override, but I have no idea when I should use them.

Question 1: Is it just for write less code in inherited contract? Question 2: If I override the function in son-contract, would it affect the function of father-contract?


Solution

  • Is it just for write less code in inherited contract?

    Generally, you can use overriding if you want to change a default behavior. Here goes a silly example that assumes most vehicles have a steering wheel, so that's the default option - but it's overridden for motorbikes.

    pragma solidity ^0.8;
    
    contract Vehicle {
        function turnRight() virtual external {
            turnSteeringWheel();
        }
    }
    
    contract Car is Vehicle {
        // no need to override turning, car has a steering wheel
    }
    
    contract Motorbike is Vehicle {
        // motorbike has a handlebar - not a steering wheel
        // so turning a steering wheel would not work
        function turnRight() override external {
            turnHandlebar();
        }
    }
    

    Overriding is also useful when you let someone else expand on your code. For example the OpenZeppelin ERC20 implementation allows you to override their default number of decimals.

    pragma solidity ^0.8;
    
    import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
    
    contract MyContract is ERC20 {
        constructor() ERC20("MyToken", "MyT") {}
    
        function decimals() override public pure returns (uint8) {
            return 2;
        }
    }
    

    If I override the function in son-contract, would it affect the function of father-contract?

    The function in the parent contract is not executed, unless the parent function is explicitly called with the super keyword.

    pragma solidity ^0.8;
    
    contract Parent {
        function foo() virtual public pure returns (uint) {
            return 1;
        }
    }
    
    contract Child is Parent {
        // not calling the Parent function, returning 2
        function foo() override public pure returns (uint) {
            return 2;
        }
    }
    
    contract Child2 is Parent {
        // calling the Parent function from within the Child function
        function foo() override public pure returns (uint) {
            uint returnedFromParent = super.foo();
    
            // 1 plus 1, returns 2
            return returnedFromParent + 1;
        }
    }