此为历史版本和 IPFS 入口查阅区,回到作品页
阿Han
IPFS 指纹 这是什么

作品指纹

【開發智能合約 — Solidity系列】實作篇Ep.13 - 抽象化的合約(Abstract Contracts)

阿Han
·
·
一起動動手來玩玩智能合約吧

圖片來源

我們在前幾篇有介紹到介面的用途,都知道介面可以制定規格,建議可以先複習一下這一篇「【開發智能合約 — Solidity系列】實作篇Ep.10 — 標準化的介面(Interfaces)」,而這次來介紹一個非常抽象的概念,名為「抽象化合約」,果然如其名! 不太容易理解,這種合約跟介面非常相似,都可以用來制定規格,而不同之處在於「抽象合約」可以被繼承,且「抽象合約」可以實作一些共同方法,但介面是不能實作的,也就是說介面有點設計的意味在,以「車」為例,介面僅設計出草圖,後續交由各種汽車、卡車…,進行不同的實作,只要遵照著規格走就好,怎麼實作就由各家決定,但「抽象合約」還可以先設計出「驅動」的方法,並藉由繼承的方式讓不同的車種皆擁有一樣的「驅動」方式,具有減少共同實作邏輯的特性。

以介面來實現,功能雖廣泛,但…

圖片來源

舉例來說,我們可能會設計一個「車」的介面,這個介面規格規定必須有「驅動」的功能,以燃油車來說會去實作「車」的介面,除了具備「驅動」以外,我們在燃油車的類別還可以實作「添加燃油」的功能,以符合燃油車的特性,那麼假設要製造其他燃油車型時,我們只要繼承「燃油車」這個類別就能基於燃油車進行擴充,以solidity語法設計如下:

// 車的介面
interface ICar {
    // 驅動
    function drive() external;
}
// 燃油車
contract FuelCar is ICar {
    // 實作燃油車的驅動方式
    function drive() public override {
        ...
    }
    // 添加燃油
    function fill() public {
        ...
    }
}
// 一般燃油轎車
contract GeneralCar is FuelCar {
    ...更多燃油車的方法
}

但…,有沒有發現,這樣的方式雖然非常直觀,但也帶來了層層實作繼承的複雜度與設計規劃的高水準。

我們用抽象合約來實現看看?

圖片來源

我們可以發現到,捨去介面後會由三層降為兩層,主要是因為抽象合約除了可以制定規格以外,也能實現共同方法,讓繼承的類別除了自行實作之外,亦可承襲共同方法。

abstract contract FuelCar {
    // 定義驅動的方法,讓繼承類別各自實作
    function drive() public virtual;
    function fill(uint amount) public {
        // 添加燃油...
    }
}
// 一般燃油轎車
contract Car is FuelCar {
    function drive() public override {
        // 實作一般燃油轎車的驅動方法
    }
}

除了能夠操作實作的「驅動」之外,亦可操作到繼承的添加函數。

圖片來源

結語

一開始在看介面與抽象類別時真的是傻傻分不清楚,兩者實在太相似了,因此有些程式語言就乾脆移除抽象類別的使用方式,但又會有別的派系支持抽象類別的使用,才會發現到市面上各種程式語言皆提倡不同的理念,有的程式語言甚至乾脆移除抽象類別的使用情境,例如: Golang…等,對我們來說多學一個念也無彷拉,只要知道其中的核心理念即可得心應手。

參考資源


CC BY-NC-ND 2.0 授权