Skip to content

Latest commit

 

History

History
106 lines (75 loc) · 2.53 KB

File metadata and controls

106 lines (75 loc) · 2.53 KB

继承

用法

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

简单继承

使用关键字is 继承父合约

多重继承

  • 继承时要按辈分最高到最低的顺序排。比如我们写一个Erzi合约,继承Yeye合约和Baba合约,那么就要写成contract Erzi is Yeye, Baba,而不能写成contract Erzi is Baba, Yeye,不然就会报错。
  • 如果某一个函数在多个继承的合约里都存在,比如例子中的hip()pop(),在子合约里必须重写,不然会报错。
  • 重写在多个父合约中都重名的函数时,override关键字后面要加上所有父合约名字,例如override(Yeye, Baba)

修饰器继承

在相应的地方加virtualoverride关键字即可

构造函数继承

有两种写法(一般使用第二种):

  1. 在继承时声明父构造函数的参数,例如:contract B is A(1)

  2. 在子合约的构造函数中声明构造函数的参数,例如:

    contract C is A {
        constructor(uint _c) A(_c * _c) {}
    }

调用父合约函数

两种方式:

  1. 直接调用: 子合约可以直接用父合约名.函数名()的方式来调用父合约函数,例如Yeye.pop()
  2. super关键字:子合约可以利用super.函数名()来调用最近的父合约函数。

钻石继承

钻石继承由基类构成的DAG(有向无环图)使其保证一个特定的顺序。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

/* 继承树:
  God
 /  \
Adam Eve
 \  /
people
*/

contract God {
    event Log(string message);

    function foo() public virtual {
        emit Log("God.foo called");
    }

    function bar() public virtual {
        emit Log("God.bar called");
    }
}

contract Adam is God {
    function foo() public virtual override {
        emit Log("Adam.foo called");
        super.foo();
    }

    function bar() public virtual override {
        emit Log("Adam.bar called");
        super.bar();
    }
}

contract Eve is God {
    function foo() public virtual override {
        emit Log("Eve.foo called");
        super.foo();
    }

    function bar() public virtual override {
        emit Log("Eve.bar called");
        super.bar();
    }
}

contract people is Adam, Eve {
    function foo() public override(Adam, Eve) {
        super.foo();
    }

    function bar() public override(Adam, Eve) {
        super.bar();
    }
}