我們先寫一個簡單的爺爺合約Yeye,裡麵包含1個Log事件和3個function: hip(), pop(), yeye(),輸出都是」Yeye」。
contract Yeye {
event Log(string msg);
// 定义3个function: hip(), pop(), man(),Log值为Yeye。
function hip() public virtual{
emit Log("Yeye");
}
function pop() public virtual{
emit Log("Yeye");
}
function yeye() public virtual {
emit Log("Yeye");
}
}
我們再定義一個爸爸合約Baba,讓他繼承Yeye合約,文法就是contract Baba is Yeye,非常直覺。在Baba合約裡,我們重寫hip()和pop()這兩個函數,加上override關鍵字,並將他們的輸出改為”Baba”;並且加一個新的函數baba,輸出也是”Baba”。
contract Baba is Yeye{
// 继承两个function: hip()和pop(),输出改为Baba。
function hip() public virtual override{
emit Log("Baba");
}
function pop() public virtual override{
emit Log("Baba");
}
function baba() public virtual{
emit Log("Baba");
}
}
多重 Solidity的合約可以繼承多個合約。規則:
繼承時要依輩分最高到最低的順序排。例如我們寫一個Erzi合約,繼承Yeye合約和Baba合約,那麼就要寫成contract Erzi is Yeye, Baba,而不能寫成contract Erzi is Baba, Yeye,不然就會報錯。
如果某一個函數在多個繼承的合約裡都存在,例如例子中的hip()和pop(),在子合約裡必須重寫,不然會報錯。
重寫在多個父合約中都重名的函數時,override關鍵字後面要加上所有父合約名字,例如override(Yeye, Baba)。
例子:
contract Erzi is Yeye, Baba{
// 继承两个function: hip()和pop(),输出值为Erzi。
function hip() public virtual override(Yeye, Baba){
emit Log("Erzi");
}
function pop() public virtual override(Yeye, Baba) {
emit Log("Erzi");
}
}
我們可以看到,Erzi合約裡面重寫了hip()和pop()兩個函數,將輸出改為”Erzi”,也分別從Yeye和Baba合約繼承了yeye()和baba()兩個函數。
修飾器 Solidity中的修飾器(Modifier)同樣可以繼承,用法與函數繼承類似,在對應的地方加virtual和override關鍵字即可。
contract Base1 {
modifier exactDividedBy2And3(uint _a) virtual {
require(_a % 2 == 0 && _a % 3 == 0);
_;
}
}
contract Identifier is Base1 {
//计算一个数分别被2除和被3除的值,但是传入的参数必须是2和3的倍数
function getExactDividedBy2And3(uint _dividend) public exactDividedBy2And3(_dividend) pure returns(uint, uint) {
return getExactDividedBy2And3WithoutModifier(_dividend);
}
//计算一个数分别被2除和被3除的值
function getExactDividedBy2And3WithoutModifier(uint _dividend) public pure returns(uint, uint){
uint div2 = _dividend / 2;
uint div3 = _dividend / 3;
return (div2, div3);
}
}