Golang的面向接口编程

          Golang的面向接口编程

                               作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

 

  之前我们分享了Go语言中的面向对象的封装和继承相关知识,今天我们来了解一下Go语言如何实现多态。

 

一.接口概述

  Go语言的接口类型用于定义一组行为,其中每个行为都由一个方法声明表示。

  接口类型中的方法声明只有方法签名而没有方法体,而方法签名包括且仅包括方法的名称,参数列表和结果返回列表。

  在Go语言中,接口是一个自定义类型,它声明了一个或者多个方法签名。接口是完全抽象的,因此不能将其实例化。然而,可以创建一个其类型为接口的变量,它可以被赋值为任何满足该接口类型的实际类型的值。

 

二.计算器案例(多态案例)

package main

import (
    "fmt"
)

//实现面向对象版本包含加减法的计算器
type Parents struct {
    x int
    y int
}

//实现加法类
type Addition struct {
    Parents
}

//实现减法类
type Subtraction struct {
    Parents
}

//实现乘法类
type multiplication struct {
    Parents
}

//实现除法类
type Division struct {
    Parents
}

func (this *Addition) Operation() int {
    return this.x + this.y
}

func (this *Subtraction) Operation() int {
    return this.x - this.y
}

func (this *multiplication) Operation() int {
    return this.x * this.y
}

func (this *Division) Operation() int {
    return this.x / this.y
}

/**
实现接口版本包含加减法的计算器

接口就是一种规范标准,接口中不做函数实现,只做定义函数格式

面向接口编程(也称为面向协议编程)降低了代码的耦合度,方便后期代码的维护和扩充,这种实现方法我们称之为多态。

多态三要素:
    1>.父类是接口;
    2>.子类实现所有的接口中定义的函数;
    3>.有一个父类接口对应子类对象指针;
*/
type MyCalculator interface {
    Operation() int //实现接口的结构体中必须包含Operation函数名且返回值为int类型
}

func Calculation(c MyCalculator) int {
    return c.Operation()
}

func main() {
    //调用加法
    a := Addition{Parents{100, 20}}
    sum := a.Operation()
    fmt.Println(sum)

    //调用减法
    b := Subtraction{Parents{100, 20}}
    sub := b.Operation()
    fmt.Println(sub)

    //调用乘法
    c := multiplication{Parents{100, 20}}
    mul := c.Operation()
    fmt.Println(mul)

    //调用除法
    d := Division{Parents{100, 20}}
    div := d.Operation()
    fmt.Println(div)

    fmt.Println("===== 我是分割线 =====")

    //调用接口,需要传入对象指针,相比上面面向对象的方法来说,接口表现了面向接口三要素中的多态特征。
    fmt.Println(Calculation(&a))
    fmt.Println(Calculation(&b))
    fmt.Println(Calculation(&c))
    fmt.Println(Calculation(&d))
}

 

三.空接口和类型断言案例

package main

import (
    "fmt"
    "reflect"
)

/**
空接口(interface{})不包含任何的方法,正因为如此,所有的类型都实现了空接口,因此空接口可以存储任意类型的数值。
如下所示,我们为空接口起了一个别名.
*/
type MyInterface interface{}

func MyPrint(input MyInterface) {
    /**
    使用断言语法获取传输过来的数据类型,类似于类型强转。
    断言语法格式如下:
        接口类型变量.(断言的类型)
    如果你不确定interface具体是什么类型,那么再断言之前最好先做判断。
    */
    output, ok := input.(int)
    if ok {
        output = input.(int) + 100 //通过断言语法可以判断数据类型
        fmt.Println(output)
    } else {
        fmt.Println(input)
    }

    inputType := reflect.TypeOf(input) //通过反射也可以判断类型
    fmt.Printf("用户传入的是:[%v],其对应的类型是[%v]\n\n", input, inputType)
}

func main() {
    m1 := true
    MyPrint(m1)

    m2 := "Jason Yin"
    MyPrint(m2)

    m3 := 2020
    MyPrint(m3)

}

 

posted @ 2020-03-21 21:36  JasonYin2020  阅读(2216)  评论(0编辑  收藏  举报