8000 Solidity中的继承:如何运行父级函数的构造函数 · Issue #68 · MagicalBridge/Blog · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Solidity中的继承:如何运行父级函数的构造函数 #68
Open
@MagicalBridge

Description

@MagicalBridge

Solidity中的继承Solidity中的多线继承这两篇文章中,我们已经学习了Solidity关于继承的相关知识点,这篇文章,我们再聊一个更细致的话题:如何运行父级函数的构造函数。

基本概念

在 Solidity 中,当一个子合约继承了父合约,并且需要在子合约的构造函数中初始化父合约的构造函数并传递参数时,可以通过在子合约的构造函数中调用父合约的构造函数来实现。这可以通过在子合约的构造函数签名后使用特殊语法来完成。

代码示例

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

// 定义父合约
contract Parent {
    uint public parentValue;

    // 父合约的构造函数,接受一个 uint 类型的参数
    constructor(uint _parentValue) {
        parentValue = _parentValue;
    }
}

// 定义子合约,继承自父合约
contract Child is Parent {
    uint public childValue;

    // 子合约的构造函数,接受两个 uint 类型的参数
    constructor(uint _parentValue, uint _childValue) Parent(_parentValue) {
        childValue = _childValue;
    }
}

在这个例子中,我们定义了一个父合约 Parent,它有一个构造函数,该构造函数接受一个 uint 类型的参数 _parentValue 并将其赋值给状态变量 parentValue

然后我们定义了一个子合约 Child,它继承自 Parent。在 Child 合约的构造函数中,我们首先指定了父合约 Parent 的构造函数,并传递了参数 _parentValue。然后,我们在子合约的构造函数中初始化子合约自己的状态变量 childValue

这种方式确保了在部署子合约 Child 时,父合约 Parent 的构造函数也能被正确地调用和初始化。

下面是一个示例,展示了如何在部署 Child 合约时传递参数:

合约部署

01.png

// 部署 Child 合约,并传递参数 42 和 100
Child child = new Child(42, 100);

// 现在可以访问 child 实例的状态变量
uint parentValue = child.parentValue(); // 42
uint childValue = child.childValue(); // 100

这样,父合约 Parent 的构造函数会被调用,并接收参数 42,而子合约 Child 的构造函数也会被调用,并接收参数 100

多线继承的场景

在 Solidity 中,合约可以多重继承自多个父合约。在这种情况下,子合约在初始化时需要明确地调用每个父合约的构造函数。父合约的构造函数将按照声明的顺序(从左到右)执行。

代码示例

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

// 定义第一个父合约 Parent1
contract Parent1 {
    uint public parent1Value;

    // 父合约的构造函数,接受一个 uint 类型的参数
    constructor(uint _parent1Value) {
        parent1Value = _parent1Value;
    }
}

// 定义第二个父合约 Parent2
contract Parent2 {
    uint public parent2Value;

    // 父合约的构造函数,接受一个 uint 类型的参数
    constructor(uint _parent2Value) {
        parent2Value = _parent2Value;
    }
}

// 定义子合约 Child,继承自 Parent1 和 Parent2
contract Child is Parent1, Parent2 {
    uint public childValue;

    // 子合约的构造函数,接受三个 uint 类型的参数
    constructor(uint _parent1Value, uint _parent2Value, uint _childValue)
        Parent1(_parent1Value) // 初始化 Parent1 的构造函数
        Parent2(_parent2Value) // 初始化 Parent2 的构造函数
    {
        childValue = _childValue;
    }
}

在这个例子中,我们定义了两个父合约 Parent1Parent2,它们各自有一个构造函数,分别接受一个 uint 类型的参数 _parent1Value_parent2Value。然后我们定义了一个子合约 Child,它继承自 Parent1Parent2

Child 合约的构造函数中,我们依次调用了 Parent1Parent2 的构造函数,并传递了相应的参数。需要注意的是,调用父合约构造函数的顺序应与继承顺序一致。

合约部署

02.png

// 部署 Child 合约,并传递参数 42, 100 和 200
Child child = new Child(42, 100, 200);

// 现在可以访问 child 实例的状态变量
uint parent1Value = child.parent1Value(); // 42
uint parent2Value = child.parent2Value(); // 100
uint childValue = child.childValue(); // 200

在部署 Child 合约时,我们传递了参数 42, 100200。这些参数分别用于初始化 Parent1Parent2 的构造函数以及 Child 自身的状态变量。

父合约的执行顺序

在多重继承的情况下,父合约的构造函数执行顺序是从左到右的。例如:

contract Child is Parent1, Parent2 { ... }

在上面的例子中,Parent1 的构造函数会先执行,然后是 Parent2 的构造函数。

这意味着在 Child 合约中,初始化 Parent1Parent2 的构造函数顺序应该与继承声明的顺序一致。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0