Solidity中的多线继承

  • Louis
  • 更新于 2024-06-22 12:32
  • 阅读 926

在Solidity中的继承这篇文章中,我介绍了solidity中关于继承的相关概念和例子。本篇文章,我们来一起探讨一个更加复杂的话题多线继承。基本概念Solidity支持多线继承,即一个合约可以同时继承多个基类合约。这可以使合约代码更加简洁,更容易复用代码

Solidity中的继承这篇文章中,我介绍了solidity中关于继承的相关概念和例子。本篇文章,我们来一起探讨一个更加复杂的话题多线继承

基本概念

Solidity支持多线继承,即一个合约可以同时继承多个基类合约。这可以使合约代码更加简洁,更容易复用代码

让我们看一个简单的例子:

代码实现

pragma solidity ^0.8.24;

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

contract B {
    function bar() public pure virtual returns (string memory) {
        return "B";
    }
}

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

    function bar() public pure override returns (string memory) {
        return "C";
    }

    function baz() public pure returns (string memory) {
        return "C";
    }
}

在这个例子中,合约 C 继承了合约 AB。这意味着 C 合约拥有所有来自 AB 合约的函数和状态变量。

C 合约中,函数 foo()bar()override 关键字标记。这意味着 C 合约提供了这两个函数的自定义实现,而不是使用来自基类合约的实现。

函数 baz()C 合约的唯一新函数。

部署示例展示

01.png

我们只需要部署合约C,从打印的结果看,所有的输出结果都是符合预期的。

多线继承中存在的问题

  • 菱形继承问题:如果多个基类合约继承自同一个基类,则会出现菱形继承问题。在这种情况下,不清楚哪个基类合约的函数和状态变量应该优先使用。

  • 函数名冲突:如果多个基类合约定义了具有相同名称的函数,则会出现函数名冲突。在这种情况下,需要使用 override 关键字显式指定要使用的函数实现。

  • 代码复杂性:多线继承会使合约代码更加复杂,难以理解和维护。

其中菱形继承问题稍微复杂一些,我们单独拿出来说明一下。

菱形继承问题

菱形继承是指一个类同时继承自多个基类,而这些基类又存在继承关系的情况。


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

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

    function bar() public pure virtual returns (string memory) {
        return "X";
    }
}

contract Y is X {
    function foo() public pure virtual  override returns (string memory) {
        return "Y";
    }
    function bar() public pure virtual  override returns (string memory) {
        return "Y";
    }
    function baz() public pure virtual returns (string memory) {
        return "Y";
    }
}

contract Z is X,Y {
    function foo() public pure override(X,Y) returns (string memory) {
        return "Z";
    }
    function bar() public pure override(X,Y) returns (string memory) {
        return "Z";
    }
    function baz() public pure override returns (string memory) {
        return "Z";
    }
}

部署之后的执行结果

02.png

关于继承的顺序问题

Solidity的继承方式是从最远的基合约到最近的基合约的顺序解决状态变量的初始化和布局;

上面代码中,Z继承了XY两个合约,需要将X写在前面,这是因为,X是最基础的合约,它没有继承任何的合约,Y继承了X合约,这部分的顺序一定要注意。

总结

在大多数情况下,建议使用单继承或接口来代替菱形继承。单继承更简单,更容易理解和维护。非必要不要使用多线继承。

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Louis
Louis
web3 developer,技术交流或者有工作机会可加VX: magicalLouis