go語言使用之介面與繼承的區別
本篇文章介紹go語言中,面向物件程式設計中繼承與介面的區別。通過案列剖析,進一步加深對兩者理解。
一、go語言的面向物件程式設計概述
我對於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開發中面向介面程式設計是非常重要的特性。
二、案例剖析
案例:實現猴子天生會爬樹,通過學習會飛翔和游泳
程式碼如下:
ackage main
import (
"fmt"
)
//定義猴子結構體
type Monkey struct {
Name string
}
func (m Monkey) climbing() {//方法
fmt.Println(m.Name, " 生來會爬樹...")
}
//定義實現飛翔介面
type BirdAble interface {
Flying()
}
//定義實現游泳介面
type FishAble interface {
Swimming()
}
type LittleMonkey struct {//繼承
Monkey //匿名欄位實現繼承
}
func (lm LittleMonkey) Flying(){
fmt.Println(lm.Name, " 通過學習會飛翔..." )
}
func (lm LittleMonkey) Swimming(){
fmt.Println(lm.Name, " 通過學習會游泳...")
}
func main() {
littleMonkey := LittleMonkey{
Monkey{"悟空"},
}
littleMonkey.climbing()//繼承
littleMonkey.Flying()//介面
littleMonkey.Swimming()//介面
}
執行結果:
悟空生來會爬樹...
悟空通過學習會飛翔...
悟空通過學習會游泳...
分析:
有以上程式碼可以看出:
1) 可以認為實現介面是對繼承的一種補充
2) 介面更加的鬆耦合,體現編碼的高內聚的特點。
三、介面與繼承的區別
1、實現方式不同:
繼承是通過匿名欄位來實現的,如:
type LittleMonkey struct {//繼承
Monkey //匿名欄位實現繼承
}
介面可以認為是通過 方法 來實現的,但與方法不盡相同,語法如下:
type 介面名 interface{
method1(引數列表) 返回值列表
method2(引數列表) 返回值列表
…
}
func (t 自定義型別) method1(引數列表) 返回值列表 {
//方法實現
}
func (t 自定義型別) method2(引數列表) 返回值列表 {
//方法實現
}
2、介面和繼承解決的解決的問題不同
繼承的價值主要在於:解決程式碼的複用性和可維護性。
介面的價值主要在於:設計好各種規範(方法),讓其它自定義型別去實現這些方法。
3、介面比繼承更加靈活
介面比繼承更加靈活,繼承是滿足 is - a的關係,而介面只需滿足 like - a的關係。
4、介面在一定程度上實現程式碼解耦
四、介面的注意點
1、在實現介面中,變數實現介面所有的方法才算是實現介面,如果只實現其中部分介面,程式碼編譯會出現恐慌(panic)。
如下程式碼:
type student1 struct{}
type action1 interface{
sport()
draw()//該方法未實現
}
func (s student1) sport() {
}
func DetailsDemo2(){
var a action1
fmt.Println("a=",a)
var s student1
// 如果沒有將介面的所有方法實現,會出現恐慌
a=s
fmt.Println("s=",s)
}
panic:
cannot use s (type student1) as type action1 in assignment:
student1 does not implement action1 (missing draw method)
2、介面中不允許存在變數
如下程式碼:
type action1 interface{
a int //變數
sport()
draw()
}
panic:
syntax error: unexpected int, expecting semicolon, newline, or }