Go 语言面向对象教程 —— 接口篇:接口组合

我们知道在 PHP 中支持接口继承以提高代码复用性:

<?php

interface A 
{
    public function foo();
}

interface B extends A
{
    public function bar();
}

class T implements B 
{
    public function foo()
{
        // do something
    }

    public function bar()
{
        // do something
    }
}

在上述代码中,我们定义了两个 PHP 接口:AB,其中接口 B 继承自 A,这样一来,如果某个类实现了接口 B,则必须实现这两个接口中声明的方法,否则会报错。

Go 语言也支持类似的「接口继承」,但是由于不支持 extends 关键字,所以其实现和类的继承一样,是通过组合来完成的。以上面这个 PHP 示例为例,在 Go 语言中,我们可以这样通过接口组合来实现接口继承,就像类的组合一样:

type A interface {
    Foo()
}

type B interface {
    A
    Bar()
}

然后我们定义一个类 T 实现接口 B

type T struct {}

func (t T) Foo() {
    fmt.Println("call Foo function from interface A.")
}

func (t T) Bar() {
    fmt.Println("call Bar function from interface B.")
}

但是,在 Go 语言中,又有些不同,因为接口实现不是强制的,是根据类实现的方法来动态判定的,比如我们上面的 T 类可以只实现 Foo 方法,也可以只实现 Bar 方法,也可以都不实现,如果只实现了 Foo 方法则 T 实现了接口 A,我们可以做这样的接口赋值

var t = T{}
var a A = t
a.Foo()

这个时候不能将 t 赋值给 B 类型接口变量,因为它没有实现 Bar 方法,则系统判定 T 没有实现接口 B,在编译时会报错:

cannot use t (type T) as type B in assignment:
        T does not implement B (missing Bar method)

如果单独实现了 Bar 方法,则既没有实现接口 A 也没有实现接口 B,只有都实现了系统才会判定实现了接口 B,才能进行相应的接口赋值:

var t = T{}
var b B = t
b.Foo()
b.Bar()

可以认为接口组合是匿名类型组合(没有显式为组合类型设置对应的属性名称)的一个特定场景,只不过接口只包含方法,而不包含任何成员变量。Go 语言底层很多包就是基于接口组合实现的,比如 io 里面的 ReaderWriterReadWriter 这些接口:

// Reader is the interface that wraps the basic Read method.
type Reader interface {
    Read(p []byte) (n int, err error)
}

// Writer is the interface that wraps the basic Write method.
type Writer interface {
    Write(p []byte) (n int, err error)
}

// ReadWriter is the interface that groups the basic Read and Write methods.
type ReadWriter interface {
    Reader
    Writer
}

本文分享自微信公众号 - 学院君的后花园(geekacademy)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-08-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Web技术布道师

如何发挥出PHP7的高性能

一点PHP博客分享如何发挥出PHP7版本中的高性能,PHP7发布也有一段时间了,但是现在还有很多小伙伴还在用PHP5.6开发项目,有的小伙伴用了PHP7只是听说...

9710
来自专栏Web技术布道师

10年开发经验的PHPer老司机经验之谈

在PHP的coding之路上不经意间已走过了10余载,期间有幸结识了一些高手,谈及成功的经验,总结下来,主要有以下几点:

13020
来自专栏Web技术布道师

从PHP 5到PHP 7性能全评测(含未发布的JIT版PHP 8对比)

导读:PHP 是 Web 开发最常用的语言,每个大版本的更新都带来不少新特性和性能提升。特别是 PHP 7.0 的发布,带来 PHP 性能飞跃。本文作者对各个 ...

16610
来自专栏Web技术布道师

关于LNMP+Frp内网穿透环境下一个PHP程序运行超时的问题

一直想在内网穿透的环境下运行WordPress,但是由于WordPress的一个插件一直运行超时错误的问题未解决而作罢,这次有空调试一下,看看能否解决:

10310
来自专栏Web技术布道师

【鸟哥】PHP7强悍性能背后,zval的变化!

PHP7已经发布, 如承诺, 我也要开始这个系列的文章的编写, 主要想通过文章让大家理解到PHP7的巨大性能提升背后到底我们做了什么, 今天我想先和大家聊聊zv...

10920
来自专栏Web技术布道师

PHP的垃圾回收机制以及大概实现

垃圾回收,简称gc。顾名思义,就是废物重利用的意思。再说这个之前先接触一下内存泄露,大概意思就是申请了一块地儿拉了会儿屎,拉完后不收拾,那么那块儿地就算是糟...

14130
来自专栏Web技术布道师

【干货】PHP7强悍性能背后,zval的变化!

PHP7已经发布, 如承诺, 我也要开始这个系列的文章的编写, 主要想通过文章让大家理解到PHP7的巨大性能提升背后到底我们做了什么, 今天我想先和大家聊聊zv...

10810
来自专栏复盘总结文章集合

JAVA通过URL链接获取视频文件信息(无需下载文件)

最近项目碰到一个大坑:APP上需要在获取视频列表时就获取视频的时长,但早期上传的时候数据库都没有保存这个数据,所以前段时间添加一个时长字段,在上传时手动输入视频...

59420
来自专栏java大数据

maven版SpringBoot的Hello World

1)新建maven项目,package方式为jar. 用archetype quick start.参考我视频目录下的SpringbootMaven项目。

16630
来自专栏Web技术布道师

Fast Web Scraping With ReactPHP

Have you ever needed to grab some data from a site that doesn’t provide a public...

14910

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励