教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 Go语言编程(十五)之接口

Go语言编程(十五)之接口

发布时间:2022-02-24   编辑:jiaochengji.com
教程集为您提供Go语言编程(十五)之接口等资源,欢迎您收藏本站,我们将为您提供最新的Go语言编程(十五)之接口资源

<span style="font-family:SimSun; font-size:14px">   接口在Go语言有着至关重要的地位。如果说goroutine和channel是支撑起Go语言的并发模型的基石,让Go语言在如今集群化与多核化的时代成为一道极为亮丽的风景,那么接口是Go语言整个类型系统的基石,让Go语言在基础编程哲学的探索上达到前所未有的高度。</span>

<span style="font-family:SimSun; font-size:14px">   Go语言在编程哲学上是变革派,而不是改良派。这不是因为Go语言有goroutine和channel,而更重要的是因为Go语言的类型系统,更是因为Go语言的接口。Go语言的编程哲学因为有接口而趋近完美。
   Go 语言的接口不单单只是接口,下面我们通过一系列对比来进一步探索Go语言的接口特性。</span>

<span style="font-family:SimSun; font-size:18px">其他语言的接口</span>

<span style="font-family:SimSun; font-size:14px">   Go语言的接口并不是其他语言(C 、Java、C#等)中所提供的接口概念。</span>

<span style="font-family:SimSun; font-size:14px">   在Go语言出现之前,接口主要作为不同组件之间的契约存在。对契约的实现是强制的,你必须声明你的确实现了该接口。为了实现一个接口,你需要从该接口继承:</span>

<span style="font-family:SimSun; font-size:14px"/>

<pre style=""><span style="color:#000080; font-weight:600">interface</span><span style="color:#c0c0c0"> </span>IFoo<span style="color:#c0c0c0"> </span><span style="color:#000000">{</span></pre> <pre style=""><span style="color:#c0c0c0">    </span>void<span style="color:#c0c0c0"> </span>Bar<span style="color:#000000">();</span></pre> <pre style=""><span style="color:#000000">}</span></pre> <pre style="">class<span style="color:#c0c0c0"> </span>Foo<span style="color:#c0c0c0"> </span>implements<span style="color:#c0c0c0"> </span>IFoo<span style="color:#c0c0c0"> </span><span style="color:#000000">{</span><span style="color:#c0c0c0"> </span><span style="color:#008000">//</span><span style="color:#c0c0c0"> </span><span style="color:#008000">Java</span></pre> <pre style=""><span style="color:#c0c0c0">    </span><span style="color:#008000">//</span><span style="color:#c0c0c0"> </span><span style="color:#008000">...</span></pre> <pre style=""><span style="color:#000000">}</span></pre> <pre style="">class<span style="color:#c0c0c0"> </span>Foo<span style="color:#c0c0c0"> </span><span style="color:#000000">:</span><span style="color:#c0c0c0"> </span>public<span style="color:#c0c0c0"> </span>IFoo<span style="color:#c0c0c0"> </span><span style="color:#000000">{</span><span style="color:#c0c0c0"> </span><span style="color:#008000">//</span><span style="color:#c0c0c0"> </span><span style="color:#008000">C </span></pre> <pre style=""><span style="color:#c0c0c0">    </span><span style="color:#008000">//</span><span style="color:#c0c0c0"> </span><span style="color:#008000">...</span></pre> <pre style=""><span style="color:#000000">}</span></pre> <pre style="">IFoo<span style="color:#000000">*</span><span style="color:#c0c0c0"> </span>foo<span style="color:#c0c0c0"> </span><span style="color:#000000">=</span><span style="color:#c0c0c0"> </span><span style="color:#000080">new</span><span style="color:#c0c0c0"> </span>Foo<span style="color:#000000">;</span></pre> 即使另外有一个接口IFoo2实现了与IFoo完全一样的接口方法甚至名字也叫IFoo只不过位于不同的名字空间下,编译器也会认为上面的类Foo只实现了IFoo而没有实现IFoo2接口。

<span style="font-family:SimSun; font-size:14px">这类接口我们称之为侵入式接口。“侵入式”的主要表现在于实现类需要明确声明自己实现了某个接口。</span>

<span style="font-family:SimSun; font-size:14px"/>

<span style="font-family:SimSun; font-size:18px">非侵入式接口</span>

<span style="font-family:SimSun; font-size:14px">   在Go语言中,一个类只需要实现了接口要求的所有函数,我们就说这个类实现了该接口,例如:</span>

<span style="font-family:SimSun; font-size:14px"/>

<pre style=""><span style="color:#000080; font-weight:600">type</span><span style="color:#c0c0c0"> </span><span style="color:#000080">File</span><span style="color:#c0c0c0"> </span><span style="color:#000080; font-weight:600">struct</span><span style="color:#c0c0c0"> </span><span style="color:#000000">{</span></pre> <pre style=""><span style="color:#c0c0c0">    </span><span style="color:#008000">//</span><span style="color:#c0c0c0"> </span><span style="color:#008000">...</span></pre> <pre style=""><span style="color:#000000">}</span></pre> <pre style=""><span style="color:#000080; font-weight:600">func</span><span style="color:#c0c0c0"> </span><span style="color:#000000">(</span>f<span style="color:#c0c0c0"> </span><span style="color:#000000">*</span><span style="color:#000080">File</span><span style="color:#000000">)</span><span style="color:#c0c0c0"> </span><span style="color:#000000">Read(</span>buf<span style="color:#c0c0c0"> </span><span style="color:#000000">[]</span><span style="color:#000080">byte</span><span style="color:#000000">)</span><span style="color:#c0c0c0"> </span><span style="color:#000000">(</span>n<span style="color:#c0c0c0"> </span><span style="color:#000080">int</span><span style="color:#000000">,</span><span style="color:#c0c0c0"> </span>err<span style="color:#c0c0c0"> </span><span style="color:#000080">error</span><span style="color:#000000">)</span></pre> <pre style=""><span style="color:#000080; font-weight:600">func</span><span style="color:#c0c0c0"> </span><span style="color:#000000">(</span>f<span style="color:#c0c0c0"> </span><span style="color:#000000">*</span><span style="color:#000080">File</span><span style="color:#000000">)</span><span style="color:#c0c0c0"> </span><span style="color:#000000">Write(</span>buf<span style="color:#c0c0c0"> </span><span style="color:#000000">[]</span><span style="color:#000080">byte</span><span style="color:#000000">)</span><span style="color:#c0c0c0"> </span><span style="color:#000000">(</span>n<span style="color:#c0c0c0"> </span><span style="color:#000080">int</span><span style="color:#000000">,</span><span style="color:#c0c0c0"> </span>err<span style="color:#c0c0c0"> </span><span style="color:#000080">error</span><span style="color:#000000">)</span></pre> <pre style=""><span style="color:#000080; font-weight:600">func</span><span style="color:#c0c0c0"> </span><span style="color:#000000">(</span>f<span style="color:#c0c0c0"> </span><span style="color:#000000">*</span><span style="color:#000080">File</span><span style="color:#000000">)</span><span style="color:#c0c0c0"> </span><span style="color:#000000">Seed(</span>off<span style="color:#c0c0c0"> </span><span style="color:#000080">int64</span><span style="color:#000000">,</span><span style="color:#c0c0c0"> </span>whence<span style="color:#c0c0c0"> </span><span style="color:#000080">int</span><span style="color:#000000">)</span><span style="color:#c0c0c0"> </span><span style="color:#000000">(</span>pos<span style="color:#c0c0c0"> </span><span style="color:#000080">int64</span><span style="color:#000000">,</span><span style="color:#c0c0c0"> </span>err<span style="color:#c0c0c0"> </span><span style="color:#000080">error</span><span style="color:#000000">)</span></pre> <pre style=""><span style="color:#000080; font-weight:600">func</span><span style="color:#c0c0c0"> </span><span style="color:#000000">(</span>f<span style="color:#c0c0c0"> </span><span style="color:#000000">*</span><span style="color:#000080">File</span><span style="color:#000000">)</span><span style="color:#c0c0c0"> </span><span style="color:#000000">CLose()</span><span style="color:#c0c0c0"> </span><span style="color:#000080">error</span></pre> 这里我们定义了一个File类,并实现有Read()、Write()、Seek()、Close()等方法。设想我们有如下接口:

<span style="font-family:SimSun; font-size:14px"/>

<pre style=""><span style="color:#000080; font-weight:600">type</span><span style="color:#c0c0c0"> </span><span style="color:#000080">IFile</span><span style="color:#c0c0c0"> </span><span style="color:#000080; font-weight:600">interface</span><span style="color:#c0c0c0"> </span><span style="color:#000000">{</span></pre> <pre style="">Read<span style="color:#000000">(</span>buf<span style="color:#c0c0c0"> </span><span style="color:#000000">[]</span><span style="color:#000080">byte</span><span style="color:#000000">)</span><span style="color:#c0c0c0"> </span><span style="color:#000000">(</span>n<span style="color:#c0c0c0"> </span><span style="color:#000080">int</span><span style="color:#000000">,</span><span style="color:#c0c0c0"> </span>err<span style="color:#c0c0c0"> </span><span style="color:#000080">error</span><span style="color:#000000">)</span></pre> <pre style="">Write<span style="color:#000000">(</span>buf<span style="color:#c0c0c0"> </span><span style="color:#000000">[]</span><span style="color:#000080">byte</span><span style="color:#000000">)</span><span style="color:#c0c0c0"> </span><span style="color:#000000">(</span>n<span style="color:#c0c0c0"> </span><span style="color:#000080">int</span><span style="color:#000000">,</span><span style="color:#c0c0c0"> </span>err<span style="color:#c0c0c0"> </span><span style="color:#000080">error</span><span style="color:#000000">)</span></pre> <pre style="">Seek<span style="color:#000000">(</span>off<span style="color:#c0c0c0"> </span><span style="color:#000080">int64</span><span style="color:#000000">,</span><span style="color:#c0c0c0"> </span>whence<span style="color:#c0c0c0"> </span><span style="color:#000080">int</span><span style="color:#000000">)</span><span style="color:#c0c0c0"> </span><span style="color:#000000">(</span>pos<span style="color:#c0c0c0"> </span><span style="color:#000080">int64</span><span style="color:#000000">,</span><span style="color:#c0c0c0"> </span>err<span style="color:#c0c0c0"> </span><span style="color:#000080">error</span><span style="color:#000000">)</span></pre> <pre style="">Close<span style="color:#000000">()</span><span style="color:#c0c0c0"> </span><span style="color:#000080">error</span></pre> <pre style=""><span style="color:#000000">}</span></pre> <pre style=""><span style="color:#000080; font-weight:600">type</span><span style="color:#c0c0c0"> </span><span style="color:#000080">IReader</span><span style="color:#c0c0c0"> </span><span style="color:#000080; font-weight:600">interface</span><span style="color:#c0c0c0"> </span><span style="color:#000000">{</span></pre> <pre style="">Read<span style="color:#000000">(</span>buf<span style="color:#c0c0c0"> </span><span style="color:#000000">[]</span><span style="color:#000080">byte</span><span style="color:#000000">)</span><span style="color:#c0c0c0"> </span><span style="color:#000000">(</span>n<span style="color:#c0c0c0"> </span><span style="color:#000080">int</span><span style="color:#000000">,</span><span style="color:#c0c0c0"> </span>err<span style="color:#c0c0c0"> </span><span style="color:#000080">error</span><span style="color:#000000">)</span></pre> <pre style=""><span style="color:#000000">}</span></pre> <pre style=""><span style="color:#000080; font-weight:600">type</span><span style="color:#c0c0c0"> </span><span style="color:#000080">IWriter</span><span style="color:#c0c0c0"> </span><span style="color:#000080; font-weight:600">interface</span><span style="color:#c0c0c0"> </span><span style="color:#000000">{</span></pre> <pre style="">Write<span style="color:#000000">(</span>buf<span style="color:#c0c0c0"> </span><span style="color:#000000">[]</span><span style="color:#000080">byte</span><span style="color:#000000">)</span><span style="color:#c0c0c0"> </span><span style="color:#000000">(</span>n<span style="color:#c0c0c0"> </span><span style="color:#000080">int</span><span style="color:#000000">,</span><span style="color:#c0c0c0"> </span>err<span style="color:#c0c0c0"> </span><span style="color:#000080">error</span><span style="color:#000000">)</span></pre> <pre style=""><span style="color:#000000">}</span></pre> <pre style=""><span style="color:#000080; font-weight:600">type</span><span style="color:#c0c0c0"> </span><span style="color:#000080">ICloser</span><span style="color:#c0c0c0"> </span><span style="color:#000080; font-weight:600">interface</span><span style="color:#c0c0c0"> </span><span style="color:#000000">{</span></pre> <pre style="">Close<span style="color:#000000">()</span><span style="color:#c0c0c0"> </span><span style="color:#000080">error</span></pre> <pre style=""><span style="color:#000000">}</span></pre> 尽管File类并没有从这些接口继承,甚至可以不知道这些接口的存在,但是File类实现了这些接口,可以进行赋值:

<span style="font-family:SimSun; font-size:14px"/>

<pre style=""><span style="color:#000080; font-weight:600">var</span><span style="color:#c0c0c0"> </span>file1<span style="color:#c0c0c0"> </span>IFile<span style="color:#c0c0c0"> </span><span style="color:#000000">=</span><span style="color:#c0c0c0"> </span><span style="color:#000080">new</span><span style="color:#000000">(</span>File<span style="color:#000000">)</span></pre> <pre style=""><span style="color:#000080; font-weight:600">var</span><span style="color:#c0c0c0"> </span>file2<span style="color:#c0c0c0"> </span>IReader<span style="color:#c0c0c0"> </span><span style="color:#000000">=</span><span style="color:#c0c0c0"> </span><span style="color:#000080">new</span><span style="color:#000000">(</span>File<span style="color:#000000">)</span></pre> <pre style=""><span style="color:#000080; font-weight:600">var</span><span style="color:#c0c0c0"> </span>file3<span style="color:#c0c0c0"> </span>IWriter<span style="color:#c0c0c0"> </span><span style="color:#000000">=</span><span style="color:#c0c0c0"> </span><span style="color:#000080">new</span><span style="color:#000000">(</span>File<span style="color:#000000">)</span></pre> <pre style=""><span style="color:#000080; font-weight:600">var</span><span style="color:#c0c0c0"> </span>file4<span style="color:#c0c0c0"> </span>ICloser<span style="color:#c0c0c0"> </span><span style="color:#000000">=</span><span style="color:#c0c0c0"> </span><span style="color:#000080">new</span><span style="color:#000000">(</span>File<span style="color:#000000">)</span></pre> Go语言的非侵入式接口,有以下优点:

<span style="font-family:SimSun; font-size:14px">其一,Go语言的标准库,再也不需要绘制类库的继承树图。</span>

<span style="font-family:SimSun; font-size:14px">其二,实现类的时候,只需要关心自己应该提供哪些方法,不用再纠结接口需要拆的多细才合理。接口由使用方按需定义,而不用事前规划。</span>

<span style="font-family:SimSun; font-size:14px">其三,不用为了实现一个接口而导入一个包。
</span>


<span style="font-family:SimSun; font-size:14px">
</span>


到此这篇关于“Go语言编程(十五)之接口”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
想系统学习GO语言(Golang
Go语言发展历史、核心、特性及学习路线
Golang学习笔记(五):Go语言与C语言的区别
Go 语言到底适合干什么?
go 获取函数地址_Go语言基础--接口浅析
[GO语言基础] 一.为什么我要学习Golang以及GO语言入门普及
Go 语言十年而立,Go2 蓄势待发
Go语言学习(十五)面向对象编程-接口
兄弟连golang神技(1)-关于 Go 语言的介绍
go语言学习笔记(十三)——接口类型

[关闭]
~ ~