変数と関数を上書きする
- override1 -> test
- override2 -> test の場合
override1.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.4.22 <0.9.0; contract override1 { string val = ""; function setVal() external { val = "override1"; } }
override2.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.4.22 <0.9.0; contract override2 { string val = ""; function setVal() external { val = "override2"; } }
test1.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.4.22 <0.9.0; import "./override1.sol"; import "./override2.sol"; contract test is override1, override2 { function getValue() external view returns(string memory) { return val; } }
コンパイルするとすでに変数も関数も存在しているので上書きできないよと怒られてしまいました。
Compiling your contracts... =========================== > Compiling ./contracts/override1.sol > Compiling ./contracts/override2.sol > Compiling ./contracts/test.sol DeclarationError: Identifier already declared. --> project:/contracts/override1.sol:5:3: | 5 | string val = ""; | ^^^^^^^^^^^^^^^ Note: The previous declaration is here: --> project:/contracts/override2.sol:5:3: | 5 | string val = ""; | ^^^^^^^^^^^^^^^ ,TypeError: Derived contract must override function "setVal". Two or more base classes define function with same name and parameter types. --> project:/contracts/test.sol:7:1: | 7 | contract test is override1, override2 { | ^ (Relevant source part starts here and spans across multiple lines). Note: Definition in "override1": --> project:/contracts/override1.sol:6:3: | 6 | function setVal() external { | ^ (Relevant source part starts here and spans across multiple lines). Note: Definition in "override2": --> project:/contracts/override2.sol:6:3: | 6 | function setVal() external { | ^ (Relevant source part starts here and spans across multiple lines).
変数と関数を上書きする(多重継承)
- override3 -> override4 -> test の場合
override3.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.4.22 <0.9.0; contract override3 { string val = ""; function setVal() external { val = "override3"; } }
override2.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.4.22 <0.9.0; import "./override3.sol"; contract override4 is override3 { string val = ""; function setVal() external { val = "override4"; } }
test2.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.4.22 <0.9.0; import "./override4.sol"; contract test is override4 { function getValue() external view returns(string memory) { return val; } }
同じくコンパイルエラーで怒られてしまいました。
Compiling your contracts... =========================== > Compiling ./contracts/override3.sol > Compiling ./contracts/override4.sol > Compiling ./contracts/test2.sol DeclarationError: Identifier already declared. --> project:/contracts/override4.sol:7:3: | 7 | string val = ""; | ^^^^^^^^^^^^^^^ Note: The previous declaration is here: --> project:/contracts/override3.sol:5:3: | 5 | string val = ""; | ^^^^^^^^^^^^^^^ ,DeclarationError: Identifier already declared. --> project:/contracts/override4.sol:7:3: | 7 | string val = ""; | ^^^^^^^^^^^^^^^ Note: The previous declaration is here: --> project:/contracts/override3.sol:5:3: | 5 | string val = ""; | ^^^^^^^^^^^^^^^ ,TypeError: Overriding function is missing "override" specifier. --> project:/contracts/override4.sol:8:3: | 8 | function setVal() external { | ^ (Relevant source part starts here and spans across multiple lines). Note: Overridden function is here: --> project:/contracts/override3.sol:6:3: | 6 | function setVal() external { | ^ (Relevant source part starts here and spans across multiple lines). ,TypeError: Trying to override non-virtual function. Did you forget to add "virtual"? --> project:/contracts/override3.sol:6:3: | 6 | function setVal() external { | ^ (Relevant source part starts here and spans across multiple lines). Note: Overriding function is here: --> project:/contracts/override4.sol:8:3: | 8 | function setVal() external { | ^ (Relevant source part starts here and spans across multiple lines).
このように override3 を変えても同様のエラーで失敗します。
// SPDX-License-Identifier: MIT pragma solidity >=0.4.22 <0.9.0; contract override3 { - string val = ""; + string val = "123"; function setVal() external { val = "override3"; } }
変数と関数を上書きする(virtual利用)
- override5 -> override6 -> test の場合
ここで公式サイトを見ていたら virtual / override を指定することで function を override できるというジャストな方法が記載されていました!!!
override5.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.4.22 <0.9.0; contract override5 { string val = ""; function setVal() virtual external { val = "override5"; } }
override6.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.4.22 <0.9.0; import "./override5.sol"; contract override6 is override5 { function setVal() external override { val = "override6"; } }
test3.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.4.22 <0.9.0; import "./override6.sol"; contract test is override6 { function getValue() external view returns(string memory) { return val; } }
これを実際に動かしてみたところ override6
がセットされていた。
truffle(develop)> compile truffle(develop)> test.new().then(i => c = i) truffle(develop)> c.getValue() '' truffle(develop)> c.setVal() truffle(develop)> c.getValue() 'override6'
まとめ
- 関数や変数の override はできない
- ただし明示的に設定をすることで関数に関しては可能になる