}
[3] override: https://learnblockchain.cn/docs/solidity/contracts.html#overriding
本翻译由登链社区[6]及Cell Network[7] 赞助。
由登链社区翻译的 Solidity 中文文档[1] 已经通过更新到 0.6.0.
uint public y;
uint public x;
}
留意 public 的状态变量仅仅可以重写外部函数( external )而且仍然不答允变量重写 internal或 public 函数。
[1] Solidity 中文文档: https://learnblockchain.cn/docs/solidity/
}
pragma solidity ^0.5.17;
function setValue(uint _x) public override(A,B) {
在solidity 0.5版中,编译器隐式地将未实现其所有函数的合约看成是抽象合约。
接口可以担任
abstract contract X {
}
uint x;
abstract contract Z is Y {
uint public x;
function f() external pure returns(uint8);
A.setValue(_x);
}
}
默认环境下,函数不再是虚函数(virtual) 。这意味着挪用非虚拟函数将始终执行该函数,而不管它的担任条理布局的其他合约。这淘汰了在solidity 0.5 中存在的歧义,在solidity 0.5版本中的所有函数都是隐式虚函数,从而可以在担任布局中进一步重写。这在大型担任中尤其危险,在这种环境下,这种歧义大概导致意外的行为和错误。
uint public x;
{
contract A {
{
意思是合约 x 应该标志为 abstract。
{
}
与面向工具编程雷同,Solidity是一种面向合约的语言,遍及利用担任和多态,而且对付语言的成长至关重要。Solidity开拓人员假如不利用这些特性很难疏散逻辑及增加代码重用性。
pragma solidity ^0.6.10;
uint256 public f = 257;
[4] 这里: https://github.com/ethereum/solidity/issues/8281
在0.5版本编译器中答允担任具有沟通名称的可见状态变量(仅在某些静态阐明东西中提示此问题)。下面的示例演示此设计的问题:
}
不再有状态变量遮蔽
[5] 溢出: [https://learnblockchain.cn/tags/%E6%95%B4%E6%95%B0%E6%BA%A2%E5%87%BA](https://learnblockchain.cn/tags/整数溢出)
pragma solidity ^0.6.10;
[2] Solidity中文文档-担任: https://learnblockchain.cn/docs/solidity/contracts.html#index-16
而对付“ B”,则是“ B.x”。因此,挪用B.setValue2(100)的功效将是将B.x配置为100,而挪用B.setValue1(200)的配置将A.x配置为200。
而在 solidity 0.6,必需显式指定,不然编译器会报错: contract X should be made abstract
}
}
y = _y;
民众变量会更安详重写外部函数
接口(interface)的函数都是隐式虚函数的,因此在实现接口时,必需在实现中显式重写其函数。 这里[4]有关此设计的接头。
function setValue1(uint _x) public { x = _x; }
function setValue(uint _x) public virtual {
function setValue(uint _x) public virtual;
值得留意的是,要害字super的事情道理与以前沟通:在扁平化担任条理布局中,super将函数挪用到更上一级的函数。外部函数(external函数)仍然不答允利用super。
譬喻,在下面的合约C中,挪用setValue会挪用最派生合约B的实现(因为 B 是担任干系的最后一个),但这在实现中并不明明。
pragma solidity ^0.5.17;
}
[6] 登链社区: https://learnblockchain.cn
interface A
function f() external pure returns(uint256);
References
function setValue(uint _x) public {
抽象合约
}
function setValue(uint _y) public {
请留意,假如合约未实现所有函数,则必需将合约标志为abstract。
uint public x;
contract B {
}
interface A
而在 solidity 0.6 会发生错误 TypeError: Overriding public state variable return types differ (范例错误:重写的民众变量返回了差异的范例),从而强制我们办理斗嘴制止溢出。
function setValue(uint _x) public virtual;
尽量此成果在0.6之前就已存在,但此刻越发安详,0.6会查抄编译器生成getter函数与外部函数的参数和返回范例是否匹配。在0.5版本,大概答允它们有所差异,如以下示例所示:
[7] Cell Network: https://www.cellnetwork.io/?utm_souce=learnblockchain
pragma solidity ^0.6.10;
pragma solidity ^0.5.17;
contract B is A
contract X {
function getValue() external override returns (uint) { return x; }
请留意,只有标志为virtual的函数才可以重写它们。另外,任何重写的函数都必需标志为override 。假如重写后依旧是可重写的,则仍然需要标志为virtual(译者注:也就是有 override 及 vritual 两个要害字标志符)。
function setValue(uint _x) external override { x = _x; }
在 A 接口上挪用 B 会返回1 , 因为 257 转换为uint8 会溢出[5]。
}
}
interface Y is X {
contract B {
}
}
pragma solidity ^0.6.10;
contract Z is Y {
pragma solidity ^0.6.10;
{
在上面的例子中,A B 各自有本身的 x, 因此,挪用B.setValue2(100)的功效将是将B.x配置为100,而挪用B.setValue1(200)的配置将A.x配置为200。
这个是solidity 0.6新增的成果,答允接口担任接口。派生的接口是的所有接口函数的组合。实现合约必需实现的所有担任接口的函数。
}
function setValue(uint _x) external override { x = _x; }
contract C is A, B {
contract B is A
function setValue(uint _x) external;
function getValue() external returns (uint);
}
利用Solidity 0.6版时,引入的主要改造除了引入接口担任、克制状态变量屏蔽之外,还使现有法则更明晰。编译器继承利用C3线性化,有关担任请拜见Solidity中文文档-担任[2]
uint public y;
contract A {
}
此刻0.6 版本克制这种用法,并激发编译器错误提示:DeclarationError: Identifier already declared (意思是变量已经声明);
interface X {
pragma solidity ^0.5.17;
contract C is A, B {
y = _y;
function setValue(uint _y) public virtual {
x = _x;
}
contract A {
而上面示例利用 0.6版编译时,编译器会报这样一个错误: Derived contract must override function “setValue”. Two or more base classes define functions with the same name and parameter types
意思是:因为父合约界说具有沟通名称和参数范例的函数,派生合约必需重写(override[3])函数“setValue”。在上面多重担任的示例中,有同一个函数是从多个父合约(合约A和B)担任。在这种环境下,,必需要重写,而且必需 override 修饰符中列出父合约。要留意重要的一点,override(A,B) 中的顺序无关紧急, 它不会改变super的行为, super仍然由担任图的C3线性化抉择,即担任干系由 contract C is A, B { … }声明的顺序抉择。
}
uint256 public override f = 257;
contract B is A {
function setValue2(uint _x) public { x = _x; }
}
显式利用 virtual 与 override
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。