golang笔记09

接口的最佳实现:

构建了结构体student还有自定义类型StudentSlice运用StudentSlice来实现接口sort.Sort,也就是三个函数:Len(),Less(i, j int)、Swap(i , j int)

代码实现:

package main

import (
	"fmt"
	"math/rand"
	"time"
	"sort"
)
//引用时间种子
type student struct{
	name string
	age int
	scores int
}

type StudentSlice []student

func (stu StudentSlice) Len() int{
	return len(stu)
}
func (stu StudentSlice) Less(i,j int)bool{
	return stu[i].scores > stu[j].scores
}
func (stu StudentSlice) Swap(i,j int){
  stu[i],stu[j] = stu[j],stu[i]
}

type Heroes struct{
	name string
	age int
}
func (hs HeroSlice)Len() int{
	return len(hs)
}
func (hs HeroSlice)Less(i,j int)bool{
	return hs[i].age > hs[j].age
}
func (hs HeroSlice)Swap(i,j int){
	hs[i],hs[j] = hs[j],hs[i]
	//进行交换
}
//完成了这三个函数那么就说这样实现了这个接口

type HeroSlice []Heroes
//自定义的类型
func main() {
	rand.Seed(time.Now().UnixNano()) //引入一个时间种子
	//引一个时间种子,这样生成的随机数就不是伪随机数
	var heroslice HeroSlice //HeroSlice已经实现了这一个接口
	for i := 0; i < 11; i++ {
		hero := Heroes{
			name: fmt.Sprintf("英雄%d", rand.Intn(100)+59),
			age:  rand.Intn(5369) + 59,
		}
		heroslice = append(heroslice, hero)
	}
	for _, v := range heroslice {
		fmt.Printf("编号 : %v ,age : %d\n", v.name, v.age)
	}
	sort.Sort(heroslice)
	fmt.Println("排序后····")
	for _, v := range heroslice {
		fmt.Printf("编号 : %v ,age : %d\n", v.name, v.age)
	}
	//输出的是根据年龄的大小来排序的从小到大

	/*	rand.Seed(time.Now().UnixNano())
		fmt.Println("n",rand.Intn(100)+1)//生成一个1~100的数字
		//定义一个数组进行排序后输出
		//可以用冒泡排序法,但是也可以运用系统提供的方法
		var numArray = []int{15,56,98,12,54,35,65}//切片定义
		fmt.Println(numArray)
		//调用前输出
		sort.Ints(numArray)//只能使用切片
		fmt.Println(numArray)//调用后输出

		var heroslice Heroes//定义一个Heroes的切片类型
		for i := 0;i<10;i++{
			hero := Heroes{
				name : fmt.Sprintf("英雄+%d",rand.Intn(100)+59),
				age : rand.Intn(100),
			}//循环中定义一个Heroes的类型的实例,再将实例放进heroslice切片当中
			heroslice = append(heroslice,hero)//进行赋值上去,对切片进行赋值
		}//想要进行排序,那么这一个自定义类型就要满足接口*/
	var stues StudentSlice
	for i := 1; i < 40; i++ {
		stu := student{
			name:   fmt.Sprintf("Student-%d", i),
			age:    rand.Intn(18),
			scores: rand.Intn(101),
		}
		stues = append(stues, stu)
	}
	for _,value :=range stues{
		fmt.Printf("学生编号:%s,\t学生成绩 :%d\n",value.name,value.scores,)
	}
	sort.Sort(stues)
	fmt.Println("排序后~")
	for index,value :=range stues{
		fmt.Printf("学生编号:%s,\t学生成绩 :%d\t排名为%d\n",value.name,value.scores,index + 1)
	}
}

实现接口和 vs 继承

继承和实现接口有什么区别吗?

代码实现:

package main

import "fmt"

type Monkey struct {
	name string
}

type BirdAble interface{
	flying()
}

type FishAble interface{
	swimming()
}
func (mokey Monkey) climming(){
	fmt.Println("Monkey生来就会爬树~")
}

type LitterMonkey struct {
	Monkey

}
func (litterm LitterMonkey) swimming(){
	fmt.Printf("%v 通过后天学习,学会了游泳~\n",litterm.name)
}
func (litterm LitterMonkey) flying(){
fmt.Printf("%v 通过后天学习,学会了飞翔~\n",litterm.name)
}

func (litterm LitterMonkey) DriveCar(){
	fmt.Printf("%v 通过后天学习,学会了开车~\n",litterm.name)
}

//type monkey struct{
//	LitterMonkey
//}

func main(){
	var litterMonkey LitterMonkey
	litterMonkey.name = "孙行者"
	litterMonkey.climming()
	litterMonkey.swimming()
	litterMonkey.flying()
	litterMonkey.DriveCar()
	//var monkey monkey
	//monkey.name = "kk"
	//monkey.DriveCar()
}

对上面代码的说明:

  • 当A结构体继承了B结构体,那么A就自动的继承了B结构体的字段和方法,并且可以直接使用
  • 当A结构体想要扩展功能(方法)时,同时又不希望去破环继承关系,那么就可以通过实现某一个接口来进行扩展,因此我们可以认为,实现接口时堆积成机制的一种补充

接口和继承解决的解决问题不同

1.继承的价值主要在于:解决代码的复用性和可维护性

2.接口的价值主要在于:设计,设计好各种规范(方法),让其它自定义类型去实现这种方法。

接口比继承更加灵活 Persion Student BiredAble LitterMonkey

接口再一定的程度上实现了代码的解耦

面向对象编程-多态

基本介绍:

变量(实例)具有多种形态。面向对象三种特征,在Go语言当中,多态特征时通过接口来实现的,可以按照同一的接口来调用不同的实现,这是接口变量就呈现了不同的形态。

快速入门:

前面的Usb接口案例,Usb usb ,既可以接收手机变量,也可以接收camera变量,多态特征

接口体现多态的两种形式:

1.多态参数

就前面的usb接口

2.多态数组

通常切片只能存储相同类型的数据,但是运用接口就可以实习储存不一样的类型的数据

代码:

package main

import "fmt"

type A interface {
	//这是一个空接口
}

type Aslice []interface{}

func main(){
	var aslice Aslice
	var a int = 10
	var str = "jack"
	var f float64 = 2.6
	aslice = append(aslice,a,str,f)
	fmt.Println(aslice)
	fmt.Println(aslice[2])
}
输出样式:
[10 jack 2.6]
2.6//第一个元素时int第二个元素时string类型,第三类型是float64

演示一个案例:给usb数组中,存放Phone结构体和Camera结构体变量

实例说明:

package main

import "fmt"

//声明一个接口
type Usb interface {
	Start()
	Stop()
}

type Phone struct{
	name string
}

func (phone Phone)Start(){
	fmt.Println(phone.name,"开始工作···")
}

func (phone Phone)Stop(){
	fmt.Println(phone.name,"停止工作····")
}

type Camera struct {
	name string
}
func (camera Camera)Start(){
	fmt.Println("相机开始工作···")
}

func (camera Camera)Stop(){
	fmt.Println("相机停止工作···")
}
type Computer struct{

}
func (cocmputer Computer)working(usb Usb){
	usb.Stop()
	usb.Start()
}



func main(){
	//定义一个usb接口数组,可以存放phone、camera的结构体变量
	//这里就体系哪里额多态数组
	var usbArr [3]Usb
	usbArr[0] = Phone{"vivo"}
	usbArr[1] = Phone{"小米"}
	usbArr[2] = Camera{"尼康"}
	fmt.Println(usbArr)
	var computer Computer
	computer.working(usbArr[0])
	computer.working(usbArr[1])
	computer.working(usbArr[2])
}

接口断言

由一个具体的需要引出来了类型断言,如何将一个接口变量,赋给一个自定义类型变量=》引出了类型断言

基本介绍:

类型断言,由于接口是一般类型,不知道具体类型,如果要转成具体类型,就需要使用类型断言

代码实现:

package main

import "fmt"

func main(){
	//类型断言的其他案例
	var x interface{}
	var b2 float32 = 1.1
	x = b2//空接口,可以接收所有类型
	//x =>float32[使用类型断言]
	y :=x.(float32)
	fmt.Println(y)
}
  • 对上面的代码说明
  1. 在进行类型断言的时候,如果类型不匹配,就会报panic,因此进行类型断言时,要确保,原来的空接口指向的就是断言的类型
  2. 如何在进行断言时,带上检测机制,如果成功就ok,否则有人不报panic
package main

import "fmt"

func main(){
	//类型断言的其他案例
	var x interface{}
	var b2 float32 = 1.1
	x = b2//空接口,可以接收所有类型
	//x =>float32[使用类型断言]
	//类型断言,待检测机制
	 y, ok := x.(float32)
	//y返回的时x转换后的值,y时运行后的是否完成的情况
	//成功就返回的时true,失败返回的时false
	 fmt.Println(y,ok)
	 if value, ok :=x.(float32);ok{
	 	fmt.Println("convert success")
	 	fmt.Printf("y 的类型时%T 值是 %v",value,value)
	 }else {
	 	fmt.Println("convert fail~")
	 }
	 fmt.Println("继续执行~")
}//返回后直接进行判断

类型断言的最佳实践1:

在前面的Usb接口案例做改进:

给Phone结构体一个特有的方法call(),当Usb接口是Phone变量时,还需要

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值