第97篇 笔记-solidity中的抽象(Abstract)

Posted wonderBlock

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第97篇 笔记-solidity中的抽象(Abstract)相关的知识,希望对你有一定的参考价值。

目录

1. 抽象合约

2. 用法

3. 接口

4. 接口的继承

5. 通过接口实现合约间调用


1. 抽象合约

如果未实现合约中的至少一个函数,则需要将合约标记为 abstract。

即使实现了所有功能,合同也可能被标记为 abstract。

抽象合约不能通过 new 操作符创建,并且不能在编译期生成字节码(bytecode)。

示例:

//SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.9.0;

abstract contract Feline 
    function utterance() public returns (bytes32);  // 定义了函数,但是没有实现(由 ; 结尾)

这样的抽象合约不能直接实例化。

2. 用法

抽象合约作为基类的用法:

//SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.9.0;

abstract contract Feline 
    function utterance() public pure returns (bytes32);


contract Cat is Feline 
    function utterance() public pure returns (bytes32)  
        return "miaow"; 
    

如果合约继承自抽象合约,并且没有通过重写来实现所有未实现的函数, 它依然需要标记为抽象 abstract 合约。

注意:没有实现的函数与 function type 不同,即使它们的语法看起来非常相似。

// 没有实现的函数示例(函数声明)
function foo(address) external returns (address);

// 函数类型的示例(变量声明,其中变量的类型为“函数”)
function(address) external returns (address) foo;

抽象合约将合约的定义与其实现脱钩,从而提供了更好的可扩展性和自文档性,并消除了代码重复。

抽象合约的使用方式与接口 interface 中定义方法的使用方式相同。

抽象合约的设计者可以这样说:“我的任何继承都必须实施此方法”。

注解:抽象合约不能用一个无实现的函数重写一个实现了的虚函数。

3. 接口

接口类似于抽象合约,但是它们不能实现任何函数。

还有进一步的限制:

  • 无法继承其他合约,不过可以继承其他接口。
  • 所有的函数都需要是 external。
  • 无法定义构造函数。
  • 无法定义状态变量。

接口基本上仅限于合约 ABI 可以表示的内容,并且 ABI 和接口之间的转换应该不会丢失任何信息。

接口由它们自己的关键字表示:

//SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.9.0;

interface Token 
    enum TokenType  Fungible, NonFungible 
    struct Coin  string obverse; string reverse; 
    function transfer(address recipient, uint amount) external;

就像继承其他合约一样,合约可以继承接口。

接口中的函数都会隐式的标记为 virtual ,意味着他们会被重写。

但是不表示重写(overriding)函数可以再次重写,仅仅当重写的函数标记为 virtual 才可以再次重写。

4. 接口的继承

接口可以继承其他的接口,遵循同样继承规则:

//SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.9.0;

interface ParentA 
    function test() external returns (uint256);


interface ParentB 
    function test() external returns (uint256);


interface SubInterface is ParentA, ParentB 
    // 必须重新定义 test 函数,以表示兼容父合约含义
    function test() external override(ParentA, ParentB) returns (uint256);

定义在接口或其他类合约( contract-like)结构体里的类型,可以在其他的合约里用这样的方式访问: Token.TokenType 或 Token.Coin

5. 通过接口实现合约间调用

参考 第92篇 合约间调用(一)

以上是关于第97篇 笔记-solidity中的抽象(Abstract)的主要内容,如果未能解决你的问题,请参考以下文章

solidity笔记——abstract用法——2021.5.10

第125篇 笔记-solidity中的编码与解码

第125篇 笔记-solidity中的编码与解码

第119篇 笔记-solidity中的ABI

第95篇 笔记-solidity中的继承(Inheritance)

第96篇 笔记-solidity中的重载(Override)