真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Solidity語法的重載,繼承的定義是什么

本篇內(nèi)容介紹了“Solidity語法的重載,繼承的定義是什么”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

創(chuàng)新互聯(lián)公司是一家網(wǎng)站設(shè)計(jì)公司,集創(chuàng)意、互聯(lián)網(wǎng)應(yīng)用、軟件技術(shù)為一體的創(chuàng)意網(wǎng)站建設(shè)服務(wù)商,主營產(chǎn)品:成都響應(yīng)式網(wǎng)站建設(shè)公司成都品牌網(wǎng)站建設(shè)、全網(wǎng)整合營銷推廣。我們專注企業(yè)品牌在網(wǎng)站中的整體樹立,網(wǎng)絡(luò)互動的體驗(yàn),以及在手機(jī)等移動端的優(yōu)質(zhì)呈現(xiàn)。成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、移動互聯(lián)產(chǎn)品、網(wǎng)絡(luò)運(yùn)營、VI設(shè)計(jì)、云產(chǎn)品.運(yùn)維為核心業(yè)務(wù)。為用戶提供一站式解決方案,我們深知市場的競爭激烈,認(rèn)真對待每位客戶,為客戶提供賞析悅目的作品,網(wǎng)站的價(jià)值服務(wù)。

1

摘要

以太坊智能合約語言Solitidy是一種面向?qū)ο蟮恼Z言。

2

合約說明

Solidity 合約類似于面向?qū)ο笳Z言中的類。合約中有用于數(shù)據(jù)持久化的狀態(tài)變量,和可以修改狀態(tài)變量的函數(shù)。 調(diào)用另一個合約實(shí)例的函數(shù)時(shí),會執(zhí)行一個 EVM 函數(shù)調(diào)用,這個操作會切換執(zhí)行時(shí)的上下文,這樣,前一個合約的狀態(tài)變量就不能訪問了。

面向?qū)ο?Object Oriented,OO)語言有3大特性:封裝,繼承,多態(tài),Solidity語言也具有著3中特性。

面向?qū)ο笳Z言3大特性的說明解釋如下:

  • 封裝(Encapsulation)

    封裝,就是把客觀事物封裝成抽象的類,并且類可以把自己的數(shù)據(jù)和方法只讓可信的類或者對象操作,對不可信的進(jìn)行信息隱藏。一個類就是一個封裝了數(shù)據(jù)以及操作這些數(shù)據(jù)的代碼的邏輯實(shí)體。在一個對象內(nèi)部,某些代碼或某些數(shù)據(jù)可以是私有的,不能被外界訪問。通過這種方式,對象對內(nèi)部數(shù)據(jù)提供了不同級別的保護(hù),以防止程序中無關(guān)的部分意外的改變或錯誤的使用了對象的私有部分。

  • 繼承(Inheritance)

    繼承,指可以讓某個類型的對象獲得另一個類型的對象的屬性的方法。它支持按級分類的概念。繼承是指這樣一種能力:它可以使用現(xiàn)有類的所有功能,并在無需重新編寫原來的類的情況下對這些功能進(jìn)行擴(kuò)展。 通過繼承創(chuàng)建的新類稱為“子類”或“派生類”,被繼承的類稱為“基類”、“父類”或“超類”。繼承的過程,就是從一般到特殊的過程。要實(shí)現(xiàn)繼承,可以通過 “繼承”(Inheritance)和“組合”(Composition)來實(shí)現(xiàn)。繼承概念的實(shí)現(xiàn)方式有二類:實(shí)現(xiàn)繼承與接口繼承。實(shí)現(xiàn)繼承是指直接使用 基類的屬性和方法而無需額外編碼的能力;接口繼承是指僅使用屬性和方法的名稱、但是子類必須提供實(shí)現(xiàn)的能力。

  • 多態(tài)(Polymorphism)

    多態(tài),是指一個類實(shí)例的相同方法在不同情形有不同表現(xiàn)形式。多態(tài)機(jī)制使具有不同內(nèi)部結(jié)構(gòu)的對象可以共享相同的外部接口。這意味著,雖然針對不同對象的具體操作不同,但通過一個公共的類,它們(那些操作)可以通過相同的方式予以調(diào)用。

    另外也解釋一下重載和重寫。

    重載(Override)是多態(tài)的一種形式,是一個類的內(nèi)部,方法中多個參數(shù),根據(jù)入?yún)⒌膫€數(shù)不同,會返回不同的結(jié)果。

    重寫(Overwrited),是子類繼承父類,重寫父類的方法。多態(tài)性是允許你將父對象設(shè)置成為一個或更多的他的子對象相等的技術(shù),賦值之后,父對象就可以根據(jù)當(dāng)前賦值給它的子對象的特性以不同的方式運(yùn)作。簡單的說,就是一句話:允許將子類類型的指針賦值給父類類型的指針。多態(tài)性在Object Pascal和C++中都是通過虛函數(shù)的。

3

函數(shù)重載(Override)

合約可以具有多個不同參數(shù)的同名函數(shù)。這也適用于繼承函數(shù)。以下示例展示了合約 A 中的重載函數(shù) f。

pragma solidity ^0.4.16;

contract A {

    function f(uint _in) public pure returns (uint out) {

        out = 1;

    }

    function f(uint _in, bytes32 _key) public pure returns (uint out) {

        out = 2; 

   }

}

重載函數(shù)也存在于外部接口中。如果兩個外部可見函數(shù)僅區(qū)別于 Solidity 內(nèi)的類型而不是它們的外部類型則會導(dǎo)致錯誤。

// 以下代碼無法編譯

pragma solidity ^0.4.16;

contract A {

    function f(B _in) public pure returns (B out) {

        out = _in;

    }

    function f(address _in) public pure returns (address out) {

        out = _in;

    }

}

contract B {

}

以上兩個 f 函數(shù)重載都接受了 ABI 的地址類型,雖然它們在 Solidity 中被認(rèn)為是不同的。

3.1 重載解析和參數(shù)匹配

通過將當(dāng)前范圍內(nèi)的函數(shù)聲明與函數(shù)調(diào)用中提供的參數(shù)相匹配,可以選擇重載函數(shù)。 如果所有參數(shù)都可以隱式地轉(zhuǎn)換為預(yù)期類型,則選擇函數(shù)作為重載候選項(xiàng)。如果一個候選都沒有,解析失敗。

pragma solidity ^0.4.16;

contract A {

    function f(uint8 _in) public pure returns (uint8 out) {

        out = _in;

    }

    function f(uint256 _in) public pure returns (uint256 out) {

        out = _in;

    }

}

調(diào)用 f(50) 會導(dǎo)致類型錯誤,因?yàn)?50 既可以被隱式轉(zhuǎn)換為 uint8 也可以被隱式轉(zhuǎn)換為 uint256。 另一方面,調(diào)用 f(256) 則會解析為 f(uint256) 重載,因?yàn)?256 不能隱式轉(zhuǎn)換為 uint8。

注解:返回參數(shù)不作為重載解析的依據(jù)。

4

繼承

通過復(fù)制包括多態(tài)的代碼,Solidity 支持多重繼承。

所有的函數(shù)調(diào)用都是虛擬的,這意味著最遠(yuǎn)的派生函數(shù)會被調(diào)用,除非明確給出合約名稱。

當(dāng)一個合約從多個合約繼承時(shí),在區(qū)塊鏈上只有一個合約被創(chuàng)建,所有基類合約的代碼被復(fù)制到創(chuàng)建的合約中。

總的來說,Solidity 的繼承系統(tǒng)與 Python的繼承系統(tǒng) ,非常 相似,特別是多重繼承方面。

下面的例子進(jìn)行了詳細(xì)的說明。

pragma solidity ^0.4.16;

contract owned {

    function owned() { owner = msg.sender;}

    address owner;

}

// 使用 is 從另一個合約派生。派生合約可以訪問所有非私有成員,包括內(nèi)部函數(shù)和狀態(tài)變量,

// 但無法通過 this 來外部訪問。

contract mortal is owned {

    function kill() {

        if (msg.sender == owner) selfdestruct(owner);

    }

}

// 這些抽象合約僅用于給編譯器提供接口。

// 注意函數(shù)沒有函數(shù)體。// 如果一個合約沒有實(shí)現(xiàn)所有函數(shù),則只能用作接口。

contract Config {

    function lookup(uint id) public returns (address adr);

}

contract NameReg {

    function register(bytes32 name) public;

    function unregister() public;

 }

// 可以多重繼承。請注意,owned 也是 mortal 的基類,

// 但只有一個 owned 實(shí)例(就像 C++ 中的虛擬繼承)。

contract named is owned, mortal {

    function named(bytes32 name) {

        Config config = Config(0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970);

        NameReg(config.lookup(1)).register(name); 

   }

    // 函數(shù)可以被另一個具有相同名稱和相同數(shù)量/類型輸入的函數(shù)重載。

    // 如果重載函數(shù)有不同類型的輸出參數(shù),會導(dǎo)致錯誤。

    // 本地和基于消息的函數(shù)調(diào)用都會考慮這些重載。

    function kill() public {

        if (msg.sender == owner) {

            Config config = Config(0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970); 

           NameReg(config.lookup(1)).unregister();

            // 仍然可以調(diào)用特定的重載函數(shù)。

            mortal.kill();

        }

    }

}

// 如果構(gòu)造函數(shù)接受參數(shù),

// 則需要在聲明(合約的構(gòu)造函數(shù))時(shí)提供,

// 或在派生合約的構(gòu)造函數(shù)位置以修飾器調(diào)用風(fēng)格提供(見下文)。

contract PriceFeed is owned, mortal, named("GoldFeed") {

   function updateInfo(uint newInfo) public {

      if (msg.sender == owner) info = newInfo;

   }

   function get() public view returns(uint r) { return info; }

   uint info;

}

注意,在上邊的代碼中,我們調(diào)用 mortal.kill() 來“轉(zhuǎn)發(fā)”銷毀請求。 這樣做法是有問題的,在下面的例子中可以看到:

pragma solidity ^0.4.0;

contract owned {

    function owned() public { owner = msg.sender;}

    address owner;

}

contract mortal is owned {

    function kill() public {

        if (msg.sender == owner) selfdestruct(owner);

    }

}

contract Base1 is mortal {

    function kill() public { /* 清除操作 1 */ mortal.kill(); }

}

contract Base2 is mortal {

    function kill() public { /* 清除操作 2 */ mortal.kill(); }

}

contract Final is Base1, Base2 {

}

調(diào)用 Final.kill() 時(shí)會調(diào)用最遠(yuǎn)的派生重載函數(shù) Base2.kill,但是會繞過 Base1.kill, 主要是因?yàn)樗踔炼疾恢?Base1 的存在。解決這個問題的方法是使用 super:

pragma solidity ^0.4.0;

contract owned {

    function owned() public { owner = msg.sender; }

    address owner;

}

contract mortal is owned {

    function kill() public {

        if (msg.sender == owner) selfdestruct(owner);

    }

}

contract Base1 is mortal {

    function kill() public { /* 清除操作 1 */ super.kill(); }

}

contract Base2 is mortal {

    function kill() public { /* 清除操作 2 */ super.kill(); }

}

contract Final is Base1, Base2 {

}

如果 Base2 調(diào)用 super 的函數(shù),它不會簡單在其基類合約上調(diào)用該函數(shù)。 相反,它在最終的繼承關(guān)系圖譜的下一個基類合約中調(diào)用這個函數(shù),所以它會調(diào)用 Base1.kill() (注意最終的繼承序列是——從最遠(yuǎn)派生合約開始:Final, Base2, Base1, mortal, ownerd)。 在類中使用 super 調(diào)用的實(shí)際函數(shù)在當(dāng)前類的上下文中是未知的,盡管它的類型是已知的。 這與普通的虛擬方法查找類似。

4.1 基類構(gòu)造函數(shù)的參數(shù)

派生合約需要提供基類構(gòu)造函數(shù)需要的所有參數(shù)。這可以通過兩種方式來完成:

pragma solidity ^0.4.0;

contract Base {

    uint x;

    function Base(uint _x) public { x = _x; }

}

contract Derived is Base(7) {

    function Derived(uint _y) Base(_y * _y) public {

    }

}

一種方法直接在繼承列表中調(diào)用基類構(gòu)造函數(shù)(is Base(7))。 另一種方法是像 修飾器modifier 使用方法一樣, 作為派生合約構(gòu)造函數(shù)定義頭的一部分,(Base(_y * _y))。 如果構(gòu)造函數(shù)參數(shù)是常量并且定義或描述了合約的行為,使用第一種方法比較方便。 如果基類構(gòu)造函數(shù)的參數(shù)依賴于派生合約,那么必須使用第二種方法。 如果像這個簡單的例子一樣,兩個地方都用到了,優(yōu)先使用 修飾器modifier 風(fēng)格的參數(shù)。

4.2 多重繼承與線性化

編程語言實(shí)現(xiàn)多重繼承需要解決幾個問題。 一個問題是 鉆石問題。 Solidity 借鑒了 Python 的方式并且使用“ C3 線性化 ”強(qiáng)制一個由基類構(gòu)成的 DAG(有向無環(huán)圖)保持一個特定的順序。 這最終反映為我們所希望的唯一化的結(jié)果,但也使某些繼承方式變?yōu)闊o效。尤其是,基類在 is 后面的順序很重要。 在下面的代碼中,Solidity 會給出“ Linearization of inheritance graph impossible ”這樣的錯誤。

// 以下代碼編譯出錯

pragma solidity ^0.4.0;

contract X {}
contract A is X {}
contract C is A, X {}

代碼編譯出錯的原因是 C 要求 X 重寫 A (因?yàn)槎x的順序是 A, X ), 但是 A 本身要求重寫 X,無法解決這種沖突。

可以通過一個簡單的規(guī)則來記憶: 以從“最接近的基類”(most base-like)到“最遠(yuǎn)的繼承”(most derived)的順序來指定所有的基類。

4.3 繼承有相同名字的不同類型成員

當(dāng)繼承導(dǎo)致一個合約具有相同名字的函數(shù)和 修飾器modifier 時(shí),這會被認(rèn)為是一個錯誤。 當(dāng)事件和 修飾器modifier 同名,或者函數(shù)和事件同名時(shí),同樣會被認(rèn)為是一個錯誤。 有一種例外情況,狀態(tài)變量的 getter 可以覆蓋一個 public 函數(shù)。

“Solidity語法的重載,繼承的定義是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!


網(wǎng)頁名稱:Solidity語法的重載,繼承的定義是什么
網(wǎng)頁鏈接:http://weahome.cn/article/jocphh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部