Solidity中的繼承

昏睡的云雪發表於2024-07-18

類似於Java中的多型,也是子繼承父,孫繼承父再繼承爺。重寫部分方法。

關鍵字:

virtual   //父類 
override  //子類

對於父類合約中的函式,在函式性質定義完之後可以加上“virtual“的關鍵字,這樣代表這個函式到子類合約中需要被重寫

contract JCA{  //充當父合約
    function foo() public pure virtual returns (string memory){
        return "A";
    }
    //新增了“virtual”代表該函式可以被重寫
    function bar() public pure virtual returns (string memory){
        return "A";
    }
    function baz() public pure  returns (string memory){
        return "A";
    }
    //沒有寫“virtual”的方法將會被繼承的子合約中
}

對於沒有寫關鍵字的函式則會將完整的函式繼承到子類合約中。

對於子類,如果只繼承一個父類合約的話,需要在開頭宣告繼承的那個父合約,不像Java中使用”extand“的關鍵字,在solidity中使用”is“如

contract JCB is JCA{  //充當子合約
    function foo() public pure override  returns(string memory){
        return "B";
    }
    //增加“override”表示覆蓋所繼承合約中的函式部分,使用後別忘了在子合約名後新增上
    //“is 父合約名”
    function bar() public pure override returns (string memory){
        return "B";
    }
}

在子類合約中只繼承一個合約時需要重寫父類合約中帶有”virtual“的函式,名相同,區別在於將”virtual“換成

”override“。

如果子類想繼承多個合約的話需要採用

contract Z is X, Y{ //合約Z繼承合約X與合約Y,如果還有則用逗號將合約名隔開

的方式,而且原則是:繼承的少的放前面。並且在合約裡對那些需要重寫的函式

 function foo() public pure override(X,Y)  returns(string memory){
        return "de";
    }    
    //如果繼承多個合約不僅在合約名哪裡需要宣告,在函式的方法裡也需要
    //用“override(X,Y)”宣告,第一個要注意繼承的順序,往後的宣告則不需要注意順序
    function bar() public pure override(Y,X)   returns (string memory){
        return "de";
    }

如果繼承的合約中其中一個也是繼承了別的合約,例如合約Y繼承了合約X,合約Z繼承了合約X和合約Y時,對合約Y裡面那些要重寫的函式

contract Y is X{ //合約Y繼承合約X
    function foo() public pure virtual override  returns(string memory){
        return "shui";
    }    
    function bar() public pure virtual override  returns (string memory){
        return "shui";
    }
     function y() public pure returns (string memory){
        return "Y";
    }
}

當父類合約中有建構函式時:

contract X { 
    string public name;
    constructor(string memory _name){
        name = _name;
    }
}

contract Y { 
    string public text;
    constructor(string memory _text){
        text = _text;
    }
}

對於子類合約,如果知道父級合約的建構函式資料型別的話則

//當父級合約中有建構函式,繼承時在父級合約的後面“(資料型別)”填寫相應型別的資料
//這個資料型別是指在父級合約中的建構函式中所定義的資料型別  
contract Z is X("yun"), Y("xue"){ //合約Z繼承合約X與合約Y  
  }

當然如果不知道父級合約建構函式的資料型別的話就需要手動輸入資料了即

contract V is X , Y{
    constructor(string memory _name ,string memory _text) X(_name) Y(_text){
        //透過自己輸入,將資料傳給父合約
    }
}

兩種方法可以混用。繼承順序影響執行順序。

相關文章