1. 程式人生 > >go語言使用之介面與繼承的區別

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 }