父合約如果允許子合約繼承并修改合約方法的話,可以加上 virtual 關鍵字
子合約重寫父合約的方法的話,需要加上override關鍵字
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
abstract contract context{
function _msgSender() internal view virtual returns (address){
return msg.sender;
}
function _masData() internal view virtual returns (bytes calldata){
return msg.data;
}
}
contract Ownable is context{
address payable public owner;
mapping(address => uint) public shares;
constructor(){
_transOwner(_msgSender());
}
modifier onlyOwner{
require(owner == _msgSender(),"not the owner");
_;
}
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
function _transOwner(address newOwner) internal virtual{
address oldOwner = owner;
owner = payable(newOwner);
emit OwnershipTransferred(oldOwner,owner);
}
function transOwner(address newOwner) public virtual onlyOwner{
require (newOwner!=address(0),"new address is zero");
_transOwner(newOwner);
}
function reannounceOwner() public virtual onlyOwner{
_transOwner(address(0));
}
function Owner() public view virtual returns (address) {
return owner;
}
function withdraw(uint _amount) onlyOwner public{
// require(shares[msg.sender] >= _amount,"not enough balance");
shares[msg.sender] -= _amount;
payable(msg.sender).transfer(_amount);
}
function exposit(uint amount) public{
shares[msg.sender]=amount;
}
function getBalance() public returns(uint bal) {
bal =shares[msg.sender];
return bal;
}
}
contract OwnablePending is Ownable{
event OwnerTranferred(address indexed oldaddress, address indexed newaddress);
address private dependingOwner;
function transOwner (address newOwner) public virtual onlyOwner override{
dependingOwner=newOwner;
emit OwnerTranferred(Owner(),dependingOwner);
}
function _transOwner(address newOwner) internal virtual override{
delete dependingOwner;
super._transOwner(newOwner); //調用繼承的最近的合約内部的方法
}
function accept()public virtual{
address sender = _msgSender();
require(sender == dependingOwner);
_transOwner(sender);
}
}
合約的繼承需要按照順序執行
A,
B<-A
C<-A,B,B 可以重寫A,如果順序颠倒的話,就會編譯錯誤
如果某一個函數在多個繼承的合約裡都存在,在子合約裡必須重寫,不然會報錯。
重寫在多個父合約中都重名的函數時,override關鍵字後面要加上所有父合約名字,例如override( B,A)。
在有向環圖的繼承關系中,鑽石繼承(菱形繼承)指一個派生類同時有兩個或兩個以上的基類。
在多重+菱形繼承鍊條上使用super關鍵字時,需要注意的是使用super會調用繼承鍊條上的每一個合約的相關函數,而不是隻調用最近的父合約。
A,
B<-A
C<-A
D<-B,C ,此時 D調用super.func(),則不是執行最近的繼父合約方法,而是按照有向環圖的方式依次向上調用,但是根合約隻會調用一次。