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 }

猜你喜欢

转载自blog.csdn.net/TDCQZD/article/details/81255363