golang 接口

golang接口

空接口

空接口相当于万能指针 可以存储任意类型数据 var kong interfance{}

// 空接口切片 var kongarr []interface{}


类型断言

  1. 直接使用变量.(类型) 例如a.(int)
  2. 断言可以将接口转换成对应的类型
func main() {

	//var arr []interface{}
	arr:=make([]interface{},5)
	arr[0]=123
	arr[1]=3.1456
	arr[2]="hello"
	arr[3]=1.234
	arr[4]=[]int{1,2,3}

	for _,v:=range arr{
		//对数据v进行类型断言
		//data,ok:=v.(int)
		//if ok{
		//	fmt.Println(data)
		//}
		if data,ok:=v.(int); ok{
			fmt.Println("整型数据:",data)
		}else if data,ok:=v.(float64);ok{
			fmt.Println("浮点型数据:",data)
		}else if data,ok:=v.(string);ok{
			fmt.Println("字符串数据:",data)
		}else if data,ok:=v.([]int);ok{
			fmt.Println("切片数据:",data)
		}
	}

}

接口语法和规则如下

接口格式 接口名一般以er结尾

type 接口名 struct{ 
    方法列表
}


// 定义接口类型 
type Hummer interface{
    // 方法,只有申明,没有实现,由别的类型(自定义类型)实现
    // 接口中的方法必须有具体的实现 就是不能是不存在的方法
    action()
}

特性: 1.接口定义了规则 方法实现了规则 2.接口是虚的 方法是实的

示范

package main

import (
	"fmt"
)

// 父类 定义变量
type Li struct {
	num int
}

// 类方法 对应一个函数 继承父类的函数

type Liux struct {
	Li
	score int
	name  string
}

func (add *Liux) Add() int {
	fmt.Println("class beggining%s score = %d num = %d", add.name, add.score, add.num)
	return add.num + 1
}
func (sub *Liux) Sub() int {
	fmt.Println("sub begenning%s score = %d num = %d", sub.name, sub.score, sub.num)
	return sub.num - 4
}

// 定义接口
type Calcer interface {
	Add() int //指向具体方法 方法必须是存在的 接口返回值放入最后面 放类型
	Sub() int
}

func main() {
	a1 := Liux{Li{33}, 23, "名字1"}
	a2 := Liux{Li{44}, 55, "名字2"}
	// 使用接口
	var cal Calcer
	cal = &a1
	c := cal.Add()
	fmt.Println(c)

	cal = &a2
	d := cal.Add()
	fmt.Println(d)
}

接口实现 先写接口再写方法

  1. 接口属于全局 可以全局调用
  2.  

多态

多态是将接口类型作为函数参数进行传递

多态是实现了接口的统一处理

示例:

package main

import (
	"fmt"
)

// 父类 定义变量
type Li struct {
	num int
}

// 类方法 对应一个函数 继承父类的函数

type Liux struct {
	Li
	score int
	name  string
}

func (add *Liux) Add() int {
	fmt.Println("class beggining%s score = %d num = %d", add.name, add.score, add.num)
	return add.num + 1
}
func (sub *Liux) Sub() int {
	fmt.Println("sub begenning%s score = %d num = %d", sub.name, sub.score, sub.num)
	return sub.num - 4
}

// 定义接口
type Calcer interface {
	Add() int //指向具体方法 方法必须是存在的 接口返回值放入最后面 放类型
	Sub() int
}

// 多态 封装函数
func Add(c Calcer) {
	c.Add()
}
func Sub(c Calcer) {
	c.Sub()
}

func main() {
	// 定义接口后不管哪种
	var c Calcer
	c = &Liux{Li{33}, 23, "名字1"}
	Add(c)

	c = &Liux{Li{44}, 55, "名字2"}
	Add(c)
}

类与多态区别以及用法

package main

import "fmt"

// 多态练习
// 1.首先定义接口 面对接口编程
type USBer interface {
	Read()
	Write()
}

// 2.定义类  创建类
type USBDev struct {
	id     int
	name   string
	rspeed int
	wspeed int
}

// 创建其他对象 可以使用基类的对象
type Mobble struct {
	USBDev  // 继承基础类方法属性
	calling string
}

// 再次定义对象
type USBFLish struct {
	USBDev // 类继承
}

// 3. 创建实现方法 指针指向智能Mobble的方法  相当于类方法 m u 指向类地址(空间)
func (m *Mobble) Read() { // 指定Mobble 方法
	m.rspeed += 20
	fmt.Printf("%s 正在读取 速度为%d\n", m.name, m.rspeed)

}
func (m *Mobble) Write() { // 指定Mobble 方法
	m.wspeed += 10
	fmt.Printf("%s 正在写入 速度为%d\n", m.name, m.wspeed)
}

//======
// 定义第二个类的类方法
func (u *USBFLish) Read() {
	u.rspeed += 30
	fmt.Printf("%s 正在读取 速度为%d\n", u.name, u.rspeed)
}
func (u *USBFLish) Write() {
	u.wspeed += 23
	fmt.Printf("%s 正在写入 速度为%d\n", u.name, u.wspeed)
}

//===============================================================================================================
// 以上皆为创建类以及类方法
//若是使用类以及类方法 可以直接

// 4. 定义接口调用函数 多态实现 将接口作为参数
func Usb(usb USBer) {
	usb.Read()
	usb.Write()
}

func main() {
	//================================================================================================================================//
	// 不使用多态 直接使用类
	//var mobble Mobble
	mobble := Mobble{USBDev{5, "class Mobble", 5, 6}, "class call"}
	mobble.Read()
	mobble.wspeed = 90 // 使用类变量并赋值的做法
	mobble.Write()
	//===============================================================================================================================//
	// 多态接口使用方法 1。 首先申明 接口 2。然后使用类地址,3 可以实用类方法了 4。可以直接忽略3 直接使用定义的函数调用定义的类以及类方法
	// 多态的目的是为了代码复用 一个指定多个复用
	//----------------------------------------------------------//
	var usb USBer                                                         // 定义申明接口 使用接口
	usb = &Mobble{USBDev{2, "this is Mobble", 20, 10}, "callingfunciton"} // 这是初始化定义类
	usb.Read()                                                            // 这是使用接口类方法

	//多态使用
	// 直接调用封装好的接口函数
	Usb(usb) // 接口函数将调用函数内所有方法并执行

	// 使用第二个 复用同个接口
	usb = &USBFLish{USBDev{66, "this is USBFLish", 80, 30}}
	Usb(usb)

}




// 打印结果如下

class Mobble 正在读取 速度为25
class Mobble 正在写入 速度为100
this is Mobble 正在读取 速度为40
this is Mobble 正在读取 速度为60
this is Mobble 正在写入 速度为20
this is USBFLish 正在读取 速度为110
this is USBFLish 正在写入 速度为53

Process finished with exit code 0

接口的继承与转换

1.接口与类一样也可以继承 接口的被继承着教子集 继承者叫做超集

package main

import (
	"fmt"
	"reflect"
)

// 接口继承
type Actioner interface {	// 子集
	Eat()
	Run()
}
type Animaler interface {		// 超集
	Actioner		//继承接口
	Bark()
	Sleep(string)
}

type Commentary struct {
	id int		// 类方法
	name string
	_type string	// 类私有方法
	dangerours int
	food string
	speed int
	voice int
}

func (animal *Commentary)Eat(){
	animal._type = "脊椎动物科"
	fmt.Printf("%s 为 %s 危险程度为 %d 食物为 %s\n",animal.name,animal._type,animal.dangerours,animal.food)
}
func (animal *Commentary)Run()  {
	animal.speed+=334
	fmt.Printf("%s 为 %s 危险程度为 %d 奔跑速度 %d\n",animal.name,animal._type,animal.dangerours,animal.speed)
}
func (animal *Commentary)Bark()  {
	animal.voice += 55
	fmt.Printf("%s 为 %s 危险程度为 %d 噪音分贝 %d\n",animal.name,animal._type,animal.dangerours,animal.voice)
}
func (animal *Commentary)Sleep(sleeptime string)  {
	fmt.Printf("%s 为 %s 睡眠时间 %s\n",animal.name,animal._type,sleeptime)
}

func Tell(tell Animaler)  {
	fmt.Println(reflect.TypeOf(tell))
	fmt.Println(tell)
	fmt.Println(tell.(*Commentary)._type)	// 取地址里面的数据 先断言然后取属性变量 断言可以将接口转换成对应的类型

	tell.Bark()
	tell.Eat()
	tell.Run()
}

func main()  {
	// 接口方法
	var Commentary1  Animaler
	Commentary1 = &Commentary{1,"猫","哺乳动物",3,"小鱼干",23,60}
	Tell(Commentary1)	// 多态
	// 类属性 类方法
	dog :=Commentary{2,"dog", "哺乳动物",5,"骨头",40,90}
	dog.Run()

	// 子集使用
	var brid Actioner
	brid = &Commentary{3,"brid","飞行动物",1,"虫子",60,20}
	brid.Run() //接口方法

	//超集使用
	var brid1 Animaler
	brid1 = &Commentary{4,"brid2","飞行动物",2,"小型动物",80,50}
	brid1.Sleep("666")  //接口方法

	//超级转换为子集 ,反过来不被允许
	brid = brid1	 // brid1 = brid 将报错 不被允许
	brid.Run()
}


运行结果
*main.Commentary
&{1 猫 哺乳动物 3 小鱼干 23 60}
哺乳动物
猫 为 哺乳动物 危险程度为 3 噪音分贝 115
猫 为 脊椎动物科 危险程度为 3 食物为 小鱼干
猫 为 脊椎动物科 危险程度为 3 奔跑速度 357
dog 为 哺乳动物 危险程度为 5 奔跑速度 374
brid 为 飞行动物 危险程度为 1 奔跑速度 394
brid2 为 飞行动物 睡眠时间 666
brid2 为 飞行动物 危险程度为 2 奔跑速度 414
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值