<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"/></svg>
本篇文章介绍go语言中,面向对象编程中继承与接口的区别。通过案列剖析,进一步加深对两者理解。
<h2 id="一go语言的面向对象编程概述">一、go语言的面向对象编程概述</h2>
我对于Go语言面向对象编程理解有以下五点:
1、Golang支持面向对象编程(OOP[object oriented programming]),但是和传统的面向对象编程有区别,并不是纯粹的面向对象语言。所以说Golang支持面向对象编程特性。
2、Golang没有类(class),Go语言的结构体(struct)和其它编程语言的类(class)有同等的地位,可以理解Golang是基于struct来实现OOP特性的。
3、Golang面向对象编程非常简洁,去掉了传统OOP语言的继承、方法重载、构造函数和析构函数、隐藏的this指针等等
4、Golang有面向对象编程的继承,封装和多态的特性,只是实现的方式和其它OOP语言不一样,比如继承 :Golang没有extends 关键字,继承是通过匿名字段来实现;多态是通过接口来实现的。
5、Golang面向对象(OOP)很优雅,OOP本身就是语言类型系统(type system)的一部分,通过接口(interface)关联,耦合性低,也非常灵活。
总之,Golang开发中面向接口编程是非常重要的特性。
<h2 id="二案例剖析">二、案例剖析</h2>
案例:实现猴子天生会爬树,通过学习会飞翔和游泳
代码如下:
<pre class="prettyprint"><code class=" hljs go">ackage main
<span class="hljs-keyword">import</span> (
<span class="hljs-string">"fmt"</span>
)
<span class="hljs-comment">//定义猴子结构体</span>
<span class="hljs-keyword">type</span> Monkey <span class="hljs-keyword">struct</span> {
Name <span class="hljs-typename">string</span>
}
<span class="hljs-keyword">func</span> (m Monkey) climbing() {<span class="hljs-comment">//方法</span>
fmt.Println(m.Name, <span class="hljs-string">" 生来会爬树..."</span>)
}
<span class="hljs-comment">//定义实现飞翔接口</span>
<span class="hljs-keyword">type</span> BirdAble <span class="hljs-keyword">interface</span> {
Flying()
}
<span class="hljs-comment">//定义实现游泳接口</span>
<span class="hljs-keyword">type</span> FishAble <span class="hljs-keyword">interface</span> {
Swimming()
}
<span class="hljs-keyword">type</span> LittleMonkey <span class="hljs-keyword">struct</span> {<span class="hljs-comment">//继承</span>
Monkey <span class="hljs-comment">//匿名字段实现继承</span>
}
<span class="hljs-keyword">func</span> (lm LittleMonkey) Flying(){
fmt.Println(lm.Name, <span class="hljs-string">" 通过学习会飞翔..."</span>)
}
<span class="hljs-keyword">func</span> (lm LittleMonkey) Swimming(){
fmt.Println(lm.Name, <span class="hljs-string">" 通过学习会游泳..."</span>)
}
<span class="hljs-keyword">func</span> main() {
littleMonkey := LittleMonkey{
Monkey{<span class="hljs-string">"悟空"</span>},
}
littleMonkey.climbing()<span class="hljs-comment">//继承</span>
littleMonkey.Flying()<span class="hljs-comment">//接口</span>
littleMonkey.Swimming()<span class="hljs-comment">//接口</span>
}
</code></pre>
运行结果:
<pre class="prettyprint"><code class=" hljs r"> 悟空生来会爬树<span class="hljs-keyword">...</span>
悟空通过学习会飞翔<span class="hljs-keyword">...</span>
悟空通过学习会游泳<span class="hljs-keyword">...</span></code></pre>
分析:
有以上代码可以看出:
1) 可以认为实现接口是对继承的一种补充
2) 接口更加的松耦合,体现编码的高内聚的特点。
<h2 id="三接口与继承的区别">三、接口与继承的区别</h2>
1、实现方式不同:
继承是通过匿名字段来实现的,如:
<pre class="prettyprint"><code class=" hljs haskell"><span class="hljs-typedef"><span class="hljs-keyword">type</span> <span class="hljs-type">LittleMonkey</span> struct <span class="hljs-container">{//继承
<span class="hljs-type">Monkey</span> //匿名字段实现继承
}</span></span>
</code></pre>
接口可以认为是通过 方法 来实现的,但与方法不尽相同,语法如下:
<pre class="prettyprint"><code class=" hljs scss">type 接口名 interface{
<span class="hljs-function">method1(参数列表)</span> 返回值列表
<span class="hljs-function">method2(参数列表)</span> 返回值列表
…
}
func (t 自定义类型) <span class="hljs-function">method1(参数列表)</span> 返回值列表 {
<span class="hljs-comment">//方法实现</span>
}
func (t 自定义类型) <span class="hljs-function">method2(参数列表)</span> 返回值列表 {
<span class="hljs-comment">//方法实现</span>
}
</code></pre>
2、接口和继承解决的解决的问题不同
继承的价值主要在于:解决代码的复用性和可维护性。
接口的价值主要在于:设计好各种规范(方法),让其它自定义类型去实现这些方法。
3、接口比继承更加灵活
接口比继承更加灵活,继承是满足 is - a的关系,而接口只需满足 like - a的关系。
4、接口在一定程度上实现代码解耦
<h2 id="四接口的注意点">四、接口的注意点</h2>
1、在实现接口中,变量实现接口所有的方法才算是实现接口,如果只实现其中部分接口,代码编译会出现恐慌(panic)。
如下代码:
<pre class="prettyprint"><code class=" hljs go"><span class="hljs-keyword">type</span> student1 <span class="hljs-keyword">struct</span>{}
<span class="hljs-keyword">type</span> action1 <span class="hljs-keyword">interface</span>{
sport()
draw()<span class="hljs-comment">//该方法未实现</span>
}
<span class="hljs-keyword">func</span> (s student1) sport() {
}
<span class="hljs-keyword">func</span> DetailsDemo2(){
<span class="hljs-keyword">var</span> a action1
fmt.Println(<span class="hljs-string">"a="</span>,a)
<span class="hljs-keyword">var</span> s student1
<span class="hljs-comment">// 如果没有将接口的所有方法实现,会出现恐慌</span>
a=s
fmt.Println(<span class="hljs-string">"s="</span>,s)
}</code></pre>
panic:
<pre class="prettyprint"><code class=" hljs oxygene">cannot use s (<span class="hljs-keyword">type</span> student1) <span class="hljs-keyword">as</span> <span class="hljs-keyword">type</span> action1 <span class="hljs-keyword">in</span> assignment:
student1 does <span class="hljs-keyword">not</span> implement action1 (missing draw <span class="hljs-function"><span class="hljs-keyword">method</span>)</span></code></pre>
2、接口中不允许存在变量
如下代码:
<pre class="prettyprint"><code class=" hljs vala">
type action1 <span class="hljs-class"><span class="hljs-keyword">interface</span>{</span>
a <span class="hljs-keyword">int</span> <span class="hljs-comment">//变量</span>
sport()
draw()
}</code></pre>
panic:
<pre class="prettyprint"><code class=" hljs vbscript">syntax <span class="hljs-keyword">error</span>: unexpected <span class="hljs-built_in">int</span>, expecting semicolon, newline, <span class="hljs-keyword">or</span> }</code></pre>
<blockquote class="layui-elem-quote" style="width: 100%;overflow:hidden">
作者: TDCQZD
链接: https://blog.csdn.net/TDCQZD/article/details/81255363
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
</blockquote>
到此这篇关于“go语言使用之接口与继承的区别”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!
您可能感兴趣的文章:
Go 语言到底适合干什么?
go语言使用之接口与继承的区别
兄弟连golang神技(1)-关于 Go 语言的介绍
基于类型系统的面向对象编程语言Go
想系统学习GO语言(Golang
浅谈golang中的接口
golang和python有什么区别?
Go语言基础之接口(面向对象编程下)
Go结构体继承指针和非指针区别(转换接口)
go语言学习-接口赋值的两种类型