0
点赞
收藏
分享

微信扫一扫

什么是无限钱包系统?有什么优势?

伊人幽梦 2024-11-06 阅读 10
区块链

1.继承

规则

// SPDX-License-Identifier: MIT
// 指定了许可证类型,MIT许可证,这是一种常用的开源许可证。

pragma solidity ^0.8.22;
// 指定了Solidity编译器的版本范围,^表示与0.8.22版本兼容的最新版本。

contract Yeye{
event Log(string msg);
function hip() public virtual{
emit Log("Yeye");
}
function pop() public virtual{
emit Log("Yeye");
}
function yeye() public virtual{
emit Log("Yeye");
}
}
contract Baba is Yeye{
function hip() public virtual override{
emit Log("Baba");
}
function pop() public virtual override{
emit Log("Baba");
}
function baba() public virtual {
emit Log("Baba");
}
}

在这个例子中,Baba继承了Yeye,并且重写了hip()和pop()函数,同时添加了一个新的函数baba()。override关键字用于明确指出函数重写了父合约中的虚拟函数。

2.多重继承

solidity的合约可以继承多个合约。规则:

   contract Erzi is Yeye,Baba{
function hip() public virtual override(Yeye,Baba){
emit Log("Erzi");
}
function pop() public virtual override(Yeye,Baba){
emit Log("Erzi");
}
}

在这个例子中,Erzi继承了Yeye和Baba,并且必须重写hip()和pop()函数,因为这两个函数在Yeye和Baba中都存在。

3.砖石继承(菱形继承)

菱形继承 (钻石继承) 是多重继承的一种特殊情况。

  A
/ \
B C
\ /
D
contract A {
function foo() public pure virtual returns (string memory) {
return "A";
}
}

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

contract C is A {
function foo() public pure virtual override returns (string memory) {
return "C";
}
}
// 根据继承顺序, B C 平级, 所以顺序随意

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

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

调用父合约的构造函数

// SPDX-License-Identifier: MIT
// 指定了许可证类型,MIT许可证,这是一种常用的开源许可证。

pragma solidity ^0.8.22;
// 指定了Solidity编译器的版本范围,^表示与0.8.22版本兼容的最新版本。

contract A{
string public name;
constructor(string memory _name){
name=_name;
}
}
contract B{
uint public number;
constructor(uint _number){
number=_number;
}
}

//方法1 在声明的继承的时候调用
contract D is A("Hello"),B(42){}

//方法2-在声明构造函数的时候调用
contract C is A,B{
constructor(string memory _name,uint _number) A(_name) B(_number){}

}
//方法1和2可混用
contract E is A("Hello"), B{
constructor(uint _number) B(_number) {}
}

构造函数的调用顺序:先继承的父合约 → 后继承的父合约 → 当前合约

所以,demo 1 是 A → B → C、 demo 2 是 A → B → D、 demo 3 是 A → B → E

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

  • 直接调用:子合约可以直接用父合约名.函数名()的方式来调用父合约函数,例如Yeye.pop()
function callParent() public{
Yeye.pop();
}
  • super关键字:子合约可以利用super.函数名()来调用最近的父合约函数。solidity继承关系按声明时从右到左的顺序是:contract Erzi is Yeye, Baba那么Baba是最近的父合约,super.pop()将调用Baba.pop()而不是Yeye.pop()
function callParentSuper() public{
// 将调用最近的父合约函数,Baba.pop()
super.pop();
}

4.总结

讲解一下完整的使用方法:

// SPDX-License-Identifier: MIT
// 这是一个许可证标识符,用于指定代码的许可证类型。MIT许可证是一种宽松的自由软件许可证。

pragma solidity ^0.8.26;
// 这行代码指定了Solidity编译器的版本。`^`符号表示与0.8.26版本兼容的最新版本。

/* Inheritance tree
A / \
B C \
/ D
*/

// 这是一个继承树的注释,说明了合约之间的继承关系。A是基类,B和C继承自A,D继承自B和C。

contract A {
// 定义了一个名为A的合约。

// 这是一个事件。你可以在函数中触发事件,并将它们记录在交易日志中。
// 在我们的例子中,这将有助于追踪函数调用。
event Log(string message);
// 事件Log被定义,它接受一个字符串参数message。

function foo() public virtual {
emit Log("A.foo called");
}
// 函数foo被定义为public,并且被标记为virtual,这意味着它可以被重写。
// 当foo被调用时,它触发了事件Log,并传递了字符串"A.foo called"。

function bar() public virtual {
emit Log("A.bar called");
}
// 函数bar也被定义为public和virtual,当bar被调用时,它触发了事件Log,并传递了字符串"A.bar called"。
}

contract B is A {
// 定义了一个名为B的合约,它继承自合约A。

function foo() public virtual override {
emit Log("B.foo called");
A.foo();
}
// 函数foo在B中被重写。它触发了事件Log,表示"B.foo called",然后调用了父合约A中的foo函数。

function bar() public virtual override {
emit Log("B.bar called");
super.bar();
}
// 函数bar在B中被重写。它触发了事件Log,表示"B.bar called",然后使用super关键字调用了父合约A中的bar函数。
}

contract C is A {
// 定义了一个名为C的合约,它继承自合约A。

function foo() public virtual override {
emit Log("C.foo called");
A.foo();
}
// 函数foo在C中被重写。它触发了事件Log,表示"C.foo called",然后调用了父合约A中的foo函数。

function bar() public virtual override {
emit Log("C.bar called");
super.bar();
}
// 函数bar在C中被重写。它触发了事件Log,表示"C.bar called",然后使用super关键字调用了父合约A中的bar函数。
}

contract D is B, C {
// 定义了一个名为D的合约,它同时继承自合约B和C。

// Try:
// - Call D.foo and check the transaction logs.
// Although D inherits A, B and C, it only called C and then A.
// - Call D.bar and check the transaction logs
// D called C, then B, and finally A.
// Although super was called twice (by B and C) it only called A once.

function foo() public override(B, C) {
super.foo();
}
// 函数foo在D中被重写。它使用super关键字调用了父合约中的foo函数。
// 由于D继承自B和C,而B和C都重写了foo函数,这里的super.foo()将调用C中的foo函数,然后C中的foo会调用A中的foo。

function bar() public override(B, C) {
super.bar();
}
// 函数bar在D中被重写。它使用super关键字调用了父合约中的bar函数。
// 由于D继承自B和C,而B和C都重写了bar函数,这里的super.bar()将首先调用C中的bar函数,然后C中的bar会调用B中的bar,最后B中的bar会调用A中的bar。
}
举报

相关推荐

0 条评论