Skip to content

Latest commit

 

History

History
90 lines (74 loc) · 3.06 KB

File metadata and controls

90 lines (74 loc) · 3.06 KB

101-13 继承

继承

继承是面向对象编程很重要的组成部分,可以显著减少重复代码。如果把合约看作是对象的话,Solidity也是面向对象的编程,也支持继承。

规则

  • virtual: 父合约中的函数,如果希望子合约重写,需要加上virtual关键字。
  • override:子合约重写了父合约中的函数,需要加上override关键字。

注意:用override修饰public变量,会重写与变量同名的getter函数.

mapping(address => uint256) public override balanceOf;

简单继承

先写一个简单的爷爷合约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{
    // 继承两个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");
    }
}

部署合约,可以看到Baba合约里有4个函数,其中hip()和pop()的输出被成功改写成”Baba”,而继承来的yeye()的输出仍然是”Yeye”

多重继承

Solidity的合约可以继承多个合约。规则如下:

  1. 继承时要按辈分最高到最低的顺序排。

  2. 如果某一个函数在多个继承的合约里都存在,在子合约里必须重写,不然会报错。

  3. 重写在多个父合约中都重名的函数时,override关键字后面要加上所有父合约名字.

修饰器的继承

Solidity中的修饰器(Modifier)同样可以继承,用法与函数继承类似,在相应的地方加virtual和override关键字即可。

构造函数的继承

子合约有两种方法继承父合约的构造函数。

  1. 在继承时声明父构造函数的参数
contract B is A(1)
  1. 在子合约的构造函数中声明构造函数的参数
contract C is A {
    constructor(uint _c) A(_c * _c) {}
}

调用父合约的函数

子合约有两种方式调用父合约的函数,直接调用和利用super关键字。

  1. 直接调用:子合约可以直接用父合约名.函数名()的方式来调用父合约函数.
function callParent() public{
    Yeye.pop();
}
  1. super关键字:子合约可以利用super.函数名()来调用最近的父合约函数。

钻石继承

在面向对象编程中,钻石继承(菱形继承)指一个派生类同时有两个或两个以上的基类。

在多重+菱形继承链条上使用super关键字时,需要注意的是使用super会调用继承链条上的每一个合约的相关函数,而不是只调用最近的父合约。