参考
这两个函数主要和继承相关。父合约将被改写的函数加virtual,子合约中的改写函数加override。
默认情况下,函数不再是虚函数(virtual) 。 这意味着调用非虚拟函数将始终执行该函数,而不管它的继承层次结构的其他合约。这减少了在solidity 0.5 中存在的歧义,在solidity 0.5版本中的所有函数都是隐式虚函数,从而可以在继承结构中进一步重写。 这在大型继承中尤其危险,在这种情况下,这种歧义可能导致意外的行为和错误。
如果父合约定义具有相同名称和参数类型的函数,子合约必须重写(override)同名函数。 在多重继承的示例中(如下),有同一个函数是从多个父合约(合约A和B)继承。在这种情况下,必须要重写,并且必须 override 修饰符中列出父合约。 要注意重要的一点,override(A,B) 中的顺序无关紧要, 它不会改变super的行为, super仍然由继承图的C3线性化决定,即继承关系由 contract C is A, B { ... }声明的顺序决定。
contract A {
uint public x;
function setValue(uint _x) public virtual {
x = _x;
}
}
contract B {
uint public y;
function setValue(uint _y) public virtual {
y = _y;
}
}
contract C is A, B {
function setValue(uint _x) public override(A,B) {
A.setValue(_x);
}
}
//继承中constructor的写法
contract A {
uint public num;
constructor (uint _num) {
num = _num;
}
}
//第一种方法 直接写入
contract B is A(23){
}
// 第二种方法 在构造方法中定义
contract B is A{
constructor (uint _num) A(_num){
}
}
//请注意,只有标记为virtual的函数才可以重写它们。 此外,任何重写的函数都必须标记为override 。 如果重写后依旧是可重写的,则仍然需要标记为virtual(译者注:也就是有 override 及 vritual 两个关键字标记符)。