Go语言自学十八式:接口和多态篇

接口定义一个对象的行为。接口只指定了对象应该做什么,至于如何实现这个行为(即实现细节),则由对象本身去确定。

在 Go 语言中,接口就是方法签名(Method Signature,MS)的集合。当一个类型定义了接口中的所有方法,我们称它实现了该接口

面向对象编程(OOP)的说法很类似:接口指定了一个类型应该具有的方法,并由该类型决定如何实现这些方法

接口的定义

使用 type 关键字来定义接口。举个栗子:

type Phone interface {
   call()
}

上面的代码定义了一个电话接口,要求实现 call 方法。

接口的实现

如果有一个类型/结构体,实现了一个接口要求的所有方法,称它实现了 Phone 接口。Go语言中接口的实现是隐式的。

接着上面的电话例子,我们先定义一个 Iphone 的结构体,而它实现了 call 的方法,所以它也是一台电话。

type Iphone struct {
    name string
}

// 接收者为 Iphone
func (phone Iphone) call() {
    fmt.Println("我是 Iphone,是一台电话")
}

接口实现多态

举个栗子,什么样子的人可以称做老师呢?

可以说只要是传授给其他人知识的,而不管你教的什么?也不管你怎么教?,都认为是老师。

这是就一个接口(老师)下,在有共同表现(育人)的不同对象(人)上的不同表现,这就是多态。

在 Go 语言中,是通过接口来实现的多态。

这里就以商品接口来写一段代码作为栗子来演示一下。先定义一个商品(Good)的接口,意思是一个类型或者结构体,只要实现了结账:settleAccount() 和订单信息: orderInfo() 两个方法,那这个类型/结构体就是一个商品。

type Good interface {
    settleAccount() int
    orderInfo() string
}

然后我们定义两个结构体,分别是手机和赠品。

type Phone struct {
    name string
    quantity int
    price int
}

type FreeGift struct {
    name string
    quantity int
    price int
}

然后分别为他们实现 Good 接口的两个方法

// Phone
func (phone Phone) settleAccount() int {
    return phone.quantity * phone.price
}
func (phone Phone) orderInfo() string{
    return "您要购买" + strconv.Itoa(phone.quantity)+ "个" + 
        phone.name + "计:" + strconv.Itoa(phone.settleAccount()) + "元"
}

// FreeGift
func (gift FreeGift) settleAccount() int {
    return 0
}
func (gift FreeGift) orderInfo() string{
    return "您要购买" + strconv.Itoa(gift.quantity)+ "个" + 
        gift.name + "计:" + strconv.Itoa(gift.settleAccount()) + "元"
}

实现了 Good 接口要求的两个方法后,手机和赠品在Go语言看来就都是商品(Good)类型了。

然后,我挑选了两件商品(实例化),分别是苹果手机(要钱)和耳机(赠品,不要钱)

iPhone := Phone{
    name:     "iPhone",
    quantity: 1,
    price:    8000,
}
earphones := FreeGift{
    name:     "耳机",
    quantity: 1,
    price:    200,
}

然后创建一个购物车(也就是类型为 Good 的切片),来存放这些商品。

goods := []Good{iPhone, earphones}

最后,定义一个方法来计算购物车里的订单金额

func calculateAllPrice(goods []Good) int {
    var allPrice int
    for _,good := range goods{
        fmt.Println(good.orderInfo())
        allPrice += good.settleAccount()
    }
    return allPrice
}

完整代码如下(供参考):

package main

import (
    "fmt"
    "strconv"
)

// 定义一个接口
type Good interface {
    settleAccount() int
    orderInfo() string
}

type Phone struct {
    name string
    quantity int
    price int
}

func (phone Phone) settleAccount() int {
    return phone.quantity * phone.price
}
func (phone Phone) orderInfo() string{
    return "您要购买" + strconv.Itoa(phone.quantity)+ "个" + 
        phone.name + "计:" + strconv.Itoa(phone.settleAccount()) + "元"
}

type FreeGift struct {
    name string
    quantity int
    price int
}

func (gift FreeGift) settleAccount() int {
    return 0
}
func (gift FreeGift) orderInfo() string{
    return "您要购买" + strconv.Itoa(gift.quantity)+ "个" + 
        gift.name + "计:" + strconv.Itoa(gift.settleAccount()) + "元"
}

func calculateAllPrice(goods []Good) int {
    var allPrice int
    for _,good := range goods{
        fmt.Println(good.orderInfo())
        allPrice += good.settleAccount()
    }
    return allPrice
}
func main()  {
    iPhone := Phone{
        name:     "iPhone",
        quantity: 1,
        price:    8000,
    }
    earphones := FreeGift{
        name:     "耳机",
        quantity: 1,
        price:    200,
    }

    goods := []Good{iPhone, earphones}
    allPrice := calculateAllPrice(goods)
    fmt.Printf("该订单总共需要支付 %d 元", allPrice)
}

运行后,输出如下:

您要购买1个iPhone计:8000元
您要购买1个耳机计:0元
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛定谔的猫96

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值