Golang_接口

接口(interface)

在Golang中,多态特性主要通过接口来体现的。

  • 为什么要有接口呢?
    • 是代码的耦合性降低,通用性增强(在现实生活中,USB就是一个接口)
  • 快速入门
    场景
package main
import "fmt"

//声明一个接口
type Usb interface{
	//声明了两个没有实现的方法
	Start()
	Stop()
}
//手机
type Phone struct{

}

//让结构体实现Usb接口的方法
func(phone Phone)Start(){
	fmt.Println("手机开始工作")
}
func(phone Phone)Stop(){
	fmt.Println("手机停止工作")
}
//相机
type Camera struct{

}
//让相机camera也实现Usb接口的方法
func(camera Camera)Start(){
	fmt.Println("相机开始工作")
}
func(camera Camera)Stop(){
	fmt.Println("相机停止工作")
}
//计算机
type Computer struct{

}

//编写一个方法Working 方法,接收一个Usb接口类型变量
//只要实现了Usb接口(所谓实现Usb接口,就是指实现了 Usb接口声明所有方法)
func (computer Computer)Working(usb Usb){
	//通过usb接口变量来调用Start和Stop方法
	usb.Start()
	usb.Stop()
}

func main(){
//测试
//先创建结构体变量
	c := Computer{}
	phone := Phone{}
	camera := Camera{}

	//关键点
	c.Working(phone)
	c.Working(camera)
}

基本介绍

  • interface类型可以定义一组方法是这些不需要实现。并且interface不能包含任何变量
  • 到某个自定义类型(比如结构体Phnoe)要使用的时候在根据具体情况把这些方法写出来(实现)

基本语法

interface语法

  • 接口里面所有方法都没有方法体。
  • 接口体现了程序设计的多态和高内聚低耦合的思想
  • Golang中的接口,不需要显示的实现。只要一个变量,含有接口类型中的所有方法,那么这个变量就实现这个接口。因此,Golang中没有implement这样的关键字

应用场景

  1. 某国要制造轰炸机、武装直升机。专家只需要把飞机需要的功能/规格定下来即可,然后让别的人具体实现就行。(功能相当于接口中未实现的方法)

  2. 现在有一个项目经理,管理三个程序员,开发一个软件,为了控制和管理软件,项目经理可以定义一些接口,然后由程序员具体实现。(项目经理定接口规范,程序员实现接口)
    在这里插入图片描述

接口注意事项

  • 接口本身不能创建实例,但是可以指向一个实现了该接口的自定义类型的变量(实例)
    在这里插入图片描述
  • 只要是自定义数据类型,就可以实现接口,不仅仅是结构体类型
    在这里插入图片描述
  • 一个自定义类型可以实现多个接口
    在这里插入图片描述
  • Golang接口中不能有任何变量
  • 一个接口(比如A接口)可以继承多个别的接口(比如B、C接口),这时如果要实现A接口,也必须将B、C接口的方法也全部实现
package main
import "fmt"

//声明接口
type AInterface interface{
	test01()
}
type BInterface interface{
	test02()
}
type CInterface interface{
	test03()
	AInterface
	BInterface
}
type Student struct{
}
//student结构体实现CInterface,则必须实现test03()、接口AInterface、BInterface中的方法
func (student Student)test01(){
	fmt.Println("student实现AInterface接口中的方法test01()")
}
func (student Student)test02(){
	fmt.Println("student实现BInterface接口中的方法test02()")
}

func (student Student)test03(){
	fmt.Println("student实现CInterface接口中的方法test03()")
}
func main(){
	var student Student
	var a CInterface = student
	a.test01()
	a.test02()
	a.test03()
}

运行结果

  • interface 类型默认是一个指针(引用类型),如果没有对interface初始化就使用,那么会输出nil
  • 空接口interface{} 没有任何方法,所以所有类型都实现了空接口,即我们可以把任何一个变量赋给空接口
    空接口代码演示

练习

  • 下面的代码,左边的没有错误;右边的会报重复定义
    练习1
  • 下面代码第 5 行是错误代码,接口(Say()方法)是Stu指针实现的,不是Stu实现的。
    在这里插入图片描述

接口编程最佳实践

  • 实现对Hero结构体切片的排序:sort.Sort(data Interface)
//sort.Sort(data Interface)里面的interface有三个方法
package main
import (
	"fmt"
	"sort"
	"math/rand"
)
//声明Hero结构体
type Hero struct{
	Name string 
	Age int
}
//声明Hero结构体的切片类型
type HeroSlice []Hero

//实现Interface接口

func (hs HeroSlice)Len()int{
	return len(hs)
}
//Less方法就是决定你使用什么标准进行排序
//1.按照Hero年龄从小到大排序
func (hs HeroSlice)Less(i, j int)bool{
	return hs[i].Age < hs[j].Age
	//修改成对Name的排序
	//只需改 return hs[i].Name < hs[j].Name
}

func (hs HeroSlice)Swap(i, j int){
	//交换
	temp := hs[i]
	hs[i] = hs[j]
	hs[j] = temp
	//简洁: hs[i], hs[j] = hs[j], hs[i] (等价于上面三句)
}


func main(){
	//先定义一个数组/切片
	var intslice = []int{0, -1, 10, 7, 90}
	//要求对 intslice切片进行排序
	//1、冒泡排序
	//2、也可以使用系统提供的方法
	sort.Ints(intslice)
	fmt.Println(intslice)

	//请大家对结构体切片进行排序
	//测试,是否可以对结构体切片进行排序
	var heros HeroSlice
	for i := 0; i < 10; i++{
		hero := Hero{
			Name : fmt.Sprintf("英雄~%d", rand.Intn(100)),
			Age : rand.Intn(100),
		}
		//将hero append 到heroes切片
		heros = append(heros, hero)
	}
	//排序前的顺序
	for _, v := range heros{
		fmt.Println(v)
	}
	//调用sort.Sort方法
	sort.Sort(heros)
	//排序后的顺序
	for _, v := range heros{
		fmt.Println("排序后的顺序", v)
	}
}

  • 将student的切片,按score从大到小排序
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值