本节是《Solidity by Example》的中文翻译与深入讲解,专为零基础或刚接触区块链开发的小白朋友打造。我们将通过“示例 + 解说 + 提示”的方式,带你逐步理解每一段 Solidity 代码的实际用途与背后的逻辑。
Solidity 是以太坊等智能合约平台使用的主要编程语言,就像写网页要用 HTML 和 JavaScript,写智能合约就需要会 Solidity。
如果你从没写过区块链代码也没关系,只要你了解一点点编程概念,比如“变量”“函数”“条件判断”,我们就能从最简单的例子开始,一步步建立你的 Solidity 编程思维。
Shadowing Inherited State Variables
继承状态变量的遮蔽(Shadowing)
与函数不同,状态变量不能通过在子合约中重新声明来覆盖(override)。
让我们学习如何正确地“覆盖”继承的状态变量。
什么是状态变量的遮蔽?
在 Solidity 中,子合约不能通过重新声明同名变量来“覆盖”父合约的状态变量(这与函数的override不同)。
- 比喻:父合约的状态变量就像家族传下来的姓氏,子合约不能直接改姓,只能在出生(构造函数)后改名。
正确做法:
- 通过构造函数或函数直接赋值,修改继承自父合约的变量。
错误做法:
- 在子合约中用同名变量重新声明,会导致编译错误。
// SPDX-License-Identifier: MIT
// 使用 MIT 许可证
pragma solidity ^0.8.26;
// 指定 Solidity 编译器版本
contract A {
string public name = "Contract A";
// 声明一个公共字符串状态变量 name,初始值为 "Contract A"
// public 自动生成 getter 函数 name()
function getName() public view returns (string memory) {
return name;
}
// 定义一个公共只读函数 getName,返回 name 的当前值
}
// 在 Solidity 0.6 及以上版本,状态变量的遮蔽(shadowing)是不允许的
// 下面的代码无法编译通过
// contract B is A {
// string public name = "Contract B";
// }
contract C is A {
// 这是正确“覆盖”继承状态变量的方法
constructor() {
name = "Contract C";
}
// 在构造函数中直接修改继承自父合约的 name 变量的值
// 调用 C.getName 会返回 "Contract C"
}
状态变量遮蔽做什么?
本质
- 状态变量不能像函数那样用
override
关键字覆盖。 - 子合约只能通过赋值(如构造函数)修改继承自父合约的变量值,不能重新声明同名变量。
比喻
- 父合约的状态变量像家族传下来的姓氏,子合约不能直接改姓,只能在出生后(构造函数)改名。