forked from dukedaily/solidity-expert
-
Notifications
You must be signed in to change notification settings - Fork 0
/
23_继承的方法_重写.md
85 lines (67 loc) · 2.17 KB
/
23_继承的方法_重写.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# 第23节:Inheritance、virtual、override
1. 合约之间存在继承关系,使用关键字:is
2. 如果父合约的方法想被子合约继承,则需要使用关键字:virtual
3. 如果子合约想覆盖父合约的方法,则需要使用关键字:override
4. 在子合约中如果想调用父合约的方法,需要使用关键字:super
5. 继承的顺序很重要,遵循最远继承,即后面继承的合约会覆盖前面父合约的方法
```js
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
/* Inheritance tree
A
/ \
B C
\ /
D
*/
contract A {
// This is called an event. You can emit events from your function
// and they are logged into the transaction log.
// In our case, this will be useful for tracing function calls.
event Log(string message);
function foo() public virtual {
emit Log("A.foo called");
}
function bar() public virtual {
emit Log("A.bar called");
}
}
contract B is A {
function foo() public virtual override {
emit Log("B.foo called");
A.foo();
}
function bar() public virtual override {
emit Log("B.bar called");
super.bar();
}
}
contract C is A {
function foo() public virtual override {
emit Log("C.foo called");
A.foo();
}
function bar() public virtual override {
emit Log("C.bar called");
super.bar();
}
}
contract D is 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();
}
function bar() public override(B, C) {
super.bar();
}
}
```
其中:
1. 调用foo的时候,由于B,C中的foo都没有使用super,所以只是覆盖问题,根据最远继承,C
覆盖了B,所以执行顺序为:D -> C -> A
2. 调用bar的时候,由于B,C中的bar使用了super,此时D的两个parent都需要执行一遍,因此为D-> C -> B -> A