Solidity语言中关于构造函数的定义:
- 构造函数是使用
constructor
关键字声明的一个可选函数; - 构造函数只在合约部署时调用一次,并用于初始化合约的状态变量;
- 如果没有显式定义的构造函数,则由编译器创建默认构造函数。
声明语法
构造函数声明语法如下:
constructor(<paramslist>) <Access Modifier> {
// todo
}
其中:
- **
constructor
:**声明构造函数的关键字; - **
<paramslist>
:**构造函数的参数列表,非必须; - **
<Access Modifier>
:**访问修饰符(即函数可见性)。构造函数的可见性可以是内部的(internal)也可以是公共的(public),内部构造函数必须将合约标记为抽象合约(在合约前添加abstract关键字)。抽象合约的参数不能被外部赋值,而仅能通过派生合约赋值。新的编译器版本无需指定访问修饰符。
例如,下面的合约声明了一个构造函数,用于对状态变量进行初始化。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
// 构造函数
contract Simple {
string str;
// 声明构造函数,并初始化状态变量
constructor() {
str = "hello simple";
}
// 定义一个函数返回状态变量的值
function getValue() public view returns(string memory) {
return str;
}
}
继承的构造函数
如果父合约没有定义构造函数,则调用默认构造函数,如果在父合约中定义了构造函数,并且有一些参数,则子合约需要提供所有参数。有两种方法来调用父合约的构造函数:
直接初始化
**例子:**在下面的例子中,使用直接初始化方法来初始化父类的构造函数。
/ SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
// 基类
contract Base {
uint data;
// 构造函数
constructor(uint _data) {
data = _data;
}
}
// 继承合约(直接初始化)
contract Derived is Base(2) {
// 构造函数
// constructor() {}
// 定义一个函数访问父合约的状态变量
function getData() external view returns(uint) {
uint result = data ** 2;
return result;
}
}
// 调用合约
contract Caller {
// 创建子合约对象
Derived c = new Derived();
// 通过子合约对象访问父合约和子合约的函数
function getResult() public view returns(uint) {
return c.getData();
}
}
输出: 我们在Remix中编译、部署和运行这个合约例子,执行结果如下图:
间接初始化
在下面的例子中,使用间接初始化方法来初始化父类的构造函数。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
// 基类
contract Base {
string str;
// 构造函数
constructor(string memory _str) {
str = _str;
}
}
// 继承合约(间接初始化)
contract Derived is Base {
// 构造函数
constructor(string memory _info) Base(_info) {}
// 定义一个函数访问父合约的状态变量
function getStr() external view returns(string memory) {
return str;
}
}
// 调用合约
contract Caller {
// 创建子合约对象
Derived c = new Derived("Hello Constructor");
// 通过子合约对象访问父合约和子合约的函数
function getResult() public view returns(string memory) {
return c.getStr();
}
}
输出: 我们在Remix中编译、部署和运行这个合约例子。执行结果如下图: