Solidity 合约继承
Solidity 语言提供了继承的支持,实现的方式是通过复制包括多态的代码到子类来实现的。Solidity 语言的合约继承通过关键字 is 来实现。
由于 Solidity 继承的实现方案是代码拷贝,所以合约继承后,部署到网络时,将变成一个合约,代码将从父类拷贝到子类中。
1. 继承示例
继承通过关键字 is 来实现,例如:
pragma solidity ^0.8.0; contract Person{ string name; uint age; } contract Man is Person{ }
2. 子类访问父类权限
子类访问父类权限修饰符包括:public、internal、private,例如:
pragma solidity ^0.8.0; contract A{ uint stateVar; function somePublicFun() public{} function someInternalFun() internal{} function somePrivateFun() private{} } contract B is A{ function call(){ //访问父类的`public`方法 somePublicFun(); //访问父类的状态变量(状态变量默认是internal权限) stateVar = 10; //访问父类的`internal`方法 someInternalFun(); //不能访问`private` //somePrivateFun(); } }
3. 传参数到父类
子类传参数到父类有两种方式:
(1). 直接传递
pragma solidity ^0.8.0; contract Base{ uint a; function Base(uint _a){ a = _a; } } contract Test is Base(1){ function getBasePara() returns(uint){ return a; } }
(2). 根据输入值传递
pragma solidity ^0.8.0; contract Base{ uint a; function Base(uint _a){ a = _a; } } contract T is Base{ function T(uint _a) Base(_a * _a){} function getBasePara() returns (uint){ return a; } }
4. 多重继承中的重名
多重继承中不允许出现相同的函数名、事件名、修改器名以及状态变量名等。
示例以下:
pragma solidity ^0.8.0; contract Employee1 { function getSalary() public pure returns(int){ return 1; } } contract Employee2 { function getSalary() public pure returns(int){ return 1; } } contract Manager is Employee1,Employee2 { }
由于基类 Employee1、Employee2 中同时包含函数 getSalary,构成重名,所以以上代码会出现编译错误。
pragma solidity ^0.8.0; contract Employee { function getSalary() public pure returns(int){ return 1; } } contract Manager is Employee { function getSalary() public pure returns(int){ return 2; } }
由于基类 Employee 和 父类 Manager 中同时包含函数 getSalary,构成重名,所以以上代码会出现编译错误。
还有一种比较隐蔽的情况,默认状态变量的getter
函数导致的重名。
示例以下:
pragma solidity ^0.8.0; contract Employee1 { uint public data = 10; } contract Employee2 { function data() returns(uint){ return 1; } } contract Manager is Employee1, Employee2{}
由于 Employee1 的状态变量 data,会默认生成 getter,函数名为 data(),于是 Employee1 和 Employee2 函数重名出错。
5. 重写函数
从 0.6 开始,solidity 引入了 abstract, virtual, override 几个关键字,用于重写函数。
示例以下:
pragma solidity ^0.8.0; contract Employee { function getSalary() public pure virtual returns(int){ return 1; } } contract Manager is Employee { function getSalary() public pure override returns(int){ return 2; } }
调用 Manager 的 getSalary 函数,将会得到结果 2。
基类中可以包含没有实现代码的函数,也就是纯虚函数,那么基类必须声明为 abstract。
示例以下:
pragma solidity ^0.8.0; abstract contract Employee { function getSalary() public pure virtual returns(int); } contract Manager is Employee { function getSalary() public pure override returns(int){ return 2; } }
Solidity 是通过回退状态的方式来处理异常错误。发生异常时会撤消当前调用及其所有子调用所改变的状态,同时给调用者返回一个错误标识。1. 条件检查Solidity 提供了assert 和 require 来进 ...