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

本文介绍了Solidity中的抽象合约和接口的概念。抽象合约允许定义未实现的功能,不能直接实例化。接口则更进一步,只能声明函数,不能实现。两者都支持继承,但接口更受限,如不能定义状态变量。接口间的继承需重写函数以兼容父接口。合约可以通过接口实现跨合约调用,提供灵活性和扩展性。
摘要由CSDN通过智能技术生成

目录

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篇 合约间调用(一)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wonderBlock

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值