ReasonJun

Solidity : Overriding (virtual / override / super) 본문

Blockchain/Solidity

Solidity : Overriding (virtual / override / super)

ReasonJun 2023. 10. 17. 00:06
728x90

The virtual and override keywords in Solidity are used to support function overriding. Function overriding allows you to redefine a function that is inherited from a base contract. This can be useful for customizing the behavior of the function for your specific needs.

 

Virtual functions

A function is marked as virtual if it can be overridden by derived contracts. When a function is marked as virtual, the Solidity compiler will generate a special opcode that allows the caller to determine which function implementation to call.

 

Override functions

A function is marked as override if it overrides a function in a base contract. The Solidity compiler will check to make sure that the override function has the same signature as the function in the base contract. If it does not, the compiler will throw an error.

 

contract Animal {
  function speak() public virtual {
    console.log("Animal sound");
  }
}

contract Dog is Animal {
  function speak() public override {
    console.log("Woof!");
  }
}

In this example, the Animal contract has a speak() function that can be overridden by derived contracts. The Dog contract overrides the speak() function to make dogs say "Woof!" instead of "Animal sound".

To use the Dog contract, we can deploy it to the blockchain and then call the speak() function on it:

Dog dog = new Dog();
dog.speak(); // Outputs "Woof!"

We can also deploy the Animal contract and then call the speak() function on it. However, since the speak() function in the Animal contract is virtual, the speak() function in the Dog contract will be called instead:

Animal animal = new Dog();
animal.speak(); // Outputs "Woof!"

This is because the Solidity compiler will check to see if the contract being called has a speak() function that overrides the speak() function in the base contract. If it does, the overriding function will be called instead.

Function overriding is a powerful feature of Solidity that allows you to customize the behavior of inherited functions for your specific needs. It can be used to create more flexible, reusable, and customizable code.

 

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

contract Student {
    function major() public pure virtual returns(string memory) {
    }
}

contract MathStudent is Student {
    function major() public pure override returns(string memory){
        return "Math";
    }
}

super

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

contract Student {

    string[] internal courses;

    function showCourses() public virtual returns(string[] memory) {
        delete courses;
        courses.push("English");
        courses.push("Music");
        return courses;
    }
}

contract ArtStudent is Student {

    function showCourses() public override  returns(string[] memory) {
        super.showCourses();
        courses.push("Art");
        return courses;
    }
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

contract Animal {
    function getName() public pure virtual returns (string memory) {
        return "Animal";
    }
}

contract Tiger is Animal {
    function getName() public pure override returns (string memory){
        return "Tiger";
    }
}

contract Turtle is Animal {
    function getName() public pure override returns (string memory){
        return "Turtle";
    }
}

contract AnimalSet {
    Animal public tiger = new Tiger();
    Animal public turtle = new Turtle();

    function getAllNames() public view returns(string memory, string memory) {
        return (tiger.getName(), turtle.getName());
    }

    function whatIsTheName(Animal _animal) public pure returns (string memory) {
        return (_animal.getName()); // input : address
    }
}
// SPDX-License-Identifier: MIT
pragma solidity >= 0.7.0 < 0.9.0;

contract ArtStudent {
    uint private schoolHours;
    constructor(uint _schoolHours) {
        schoolHours = _schoolHours;
    }

    function time() public virtual returns(uint) {
        return 5;
    }
}

contract PartTimer {
    uint private workingHours;
    constructor(uint _workingHours){
        workingHours = _workingHours;
    }
    function time() public  virtual  returns (uint) {
        return workingHours;
    }
}

contract Alice is  PartTimer(6), ArtStudent(5) { // The contract behind it becomes super.
    function time() public override (PartTimer, ArtStudent) returns (uint) {
        return super.time();
    }
}
728x90

'Blockchain > Solidity' 카테고리의 다른 글

Solidity : interface  (0) 2023.10.17
Solidity : abstract  (0) 2023.10.17
Solidity : Overloading  (1) 2023.10.16
Solidity: Encapsulation  (0) 2023.10.16
Solidity : Inheritance (is, override / Multiple)  (0) 2023.10.16
Comments