《Solidity笔记》继承和重写

69 阅读2分钟

1. 继承概述

  • 继承:允许合约继承另一个合约的功能,使用 is 关键字。

2. 基本继承语法

contract A {
    function foo() public pure returns (string memory) {
        return "A";
    }
}

contract B is A {
    function bar() public pure returns (string memory) {
        return "B";
    }
}
  • B 继承 A 的所有公开和内部函数。

3. 多重继承

  • 支持多重继承,后继承的合约会覆盖前面的同名函数。
contract C is A, B {
    function baz() public pure returns (string memory) {
        return "C";
    }
}

4. 函数重写

  • 使用 virtualoverride 关键字重写函数。
contract A {
    function foo() public pure virtual returns (string memory) {
        return "A";
    }
}

contract B is A {
    function foo() public pure override returns (string memory) {
        return "B";
    }
}

5. 调用父合约函数

  • 使用 super 关键字调用父合约函数。
contract B is A {
    function foo() public pure override returns (string memory) {
        return string(abi.encodePacked(super.foo(), " and B"));
    }
}

6. 构造函数的继承

  • 子合约的构造函数可以调用父合约的构造函数。
contract A {
    uint public x;
    constructor(uint _x) {
        x = _x;
    }
}

contract B is A {
    constructor(uint _x) A(_x) {}
}

7. 访问控制

  • publicinternal 函数可以被继承和重写,private 函数不能被继承。
  • external 函数不能被子合约调用,只能通过交易调用。

8. 接口和抽象合约

  • 接口(interface):定义函数声明,所有函数必须是 external
interface IExample {
    function foo() external;
}
  • 抽象合约(abstract contract):包含函数声明和部分实现,不能部署。
abstract contract A {
    function foo() public virtual;
    function bar() public pure returns (string memory) {
        return "bar";
    }
}

contract B is A {
    function foo() public override {
        // 实现 foo 函数
    }
}

总结

  • 继承实现代码复用,支持单继承和多重继承。
  • 使用 virtualoverride 重写函数,super 调用父合约函数。
  • 子合约构造函数可以调用父合约的构造函数。
  • 接口和抽象合约提供灵活的代码组织方式。