go的接口详解

news/2024/11/22 23:43:07/

接口的定义和格式

接口(interface)是一种类型,用来定义行为(方法)。这句话有两个重点,类型定义行为

首先解释定义行为:

接口即一组方法定义的集合,定义了对象的一组行为,就是定义了一些函数,由具体的类型实例实现具体的方法。

换句话说,一个接口就是定义(规范或约束),接口并不会实现这些方法,具体的实现由类实现,实现接口的类必须严格按照接口的声明来实现接口提供的所有功能。接口的作用应该是将定义与实现分离,降低耦合度。

在多人合作开发同一个项目时,​接口表示调用者和设计者的一种约定,事先定义好相互调用的接口可以大大提高开发的效率。有了接口,就可以在不影响现有接口声明的情况下,修改接口的内部实现,从而使兼容性问题最小化。

 接口的定义格式:

type Namer interface {Method1(param_list) return_type  //方法名(参数列表) 返回值列表Method2(param_list) return_type  //方法名(参数列表) 返回值列表<br>   ...... }

代码

定义Flyable接口

type Flyable interface {Fly()

实现与使用

实现

实现了接口的所有方法,就是实现了该接口,不需要显示指明是哪个接口,即隐式实现

func (w *WuKong) Fly() {fmt.Println("筋斗云,来...")
}

多接口实现

再定义一个接口

type Swimmable interface {Swim()
}

实现

func (w *WuKong) Swim()  {fmt.Println("老龙王,俺老孙的金箍棒呢?")
}

 WuKong结构体就实现了上面的两个接口。

接口继承

再定义一个接口Skills,继承前面的两个接口,并添加新的方法Change

type Skills interface {FlyableSwimmableChange()
}

实现

func (w *WuKong) Change()  {fmt.Println("看我72变...")
}

 至此, WuKong结构体实现了四个接口,为什么是四个呢?因为还有下面这一个

空接口

type Null interface {}

如你所见,什么方法也没有,即每个结构体都实现了空接口,都可以赋值给空接口,这在排序,后面类型断言等部分都很有用。 

  1. interface (interface {}) 不包含任何的 method
  2. 正因为如此,所有的类型都实现了空 interface
  3. interface 对于描述起不到任何的作用 (因为它不包含任何的 method),但是空 interface 在我们需要存储任意类型的数值的时候相当有用,因为它可以存储任意类型的数值。
func main() {// 定义 a 为空接口var a interface{}var i int = 5s := "Hello world"// a 可以存储任意类型的数值a = ia = sfmt.Println(a)
}

一个函数把 interface {} 作为参数,那么他可以接受任意类型的值作为参数,如果一个函数返回 interface {}, 那么也就可以返回任意类型的值。是不是很有用!

隐式实现及实现条件

怎么实现接口:
实现接口的类并不需要显式声明,只需要实现接口所有的函数就表示实现了该接口,而且类还可以拥有自己的方法。

接口能被哪些类型实现:
接口可以被结构体实现,也可以被函数类型实现。
接口被实现的条件:
接口被实现的条件一:接口的方法与实现接口的类型方法格式一致(方法名、参数类型、返回值类型一致)。
接口被实现的条件二:接口中所有方法均被实现。

package mainimport "fmt"type Shaper interface{Area() float64//Perimeter() float64type Rectangle struct{length float64width float64}//实现Shaper接口中的方法func (r*Rectangle) Area() float64{return r.length*r.width}//Set是属于Rectangle的方法func (r*Rectangle) SetLength(l float64){r.length=lr.width=w}func main(){rect :=new(Rectangle)rect.Set(2,3)areaIntf :=Shaper(rect)//这里将指针类型实例赋值给接口fmt.Println(:The rect has area:%f\n,areaIntf.Area())}
}

接口赋值

现在来解释接口是一个类型,本质是一个指针类型,那么什么样的值可以赋值给接口,有两种:实现了该接口的类或者接口

1.将对象赋值给接口
当接口实例中保存了自定义类型的实例后,就可以直接从接口上调用它所保存的实例的方法。

package mainimport "fmt"//定义接口
type Testinterface interface{Teststring() string Testint() int
}
//定义结构体
type TestMethod struct{name string age int
}//结构体的两个方法隐式实现了接口
func(t*TestMethod)Teststring() string{return t.name
}//结构体的两个方法隐式实现了接口
func(t*TestMethod)Testint() int{return t.age
}func main(){T1 :=&TestMethod{"ling",34}T2 :=TestMethod{"li",23}//接口的本质是一个类型//接口赋值,只要类实现了该接口的所有方法即可将该类赋值给这个接口var Test1 Testinterface//接口只能是值类型Test1 =T1//TestMethod类的指针类型实例传给接口fmt.Println(Test1.Teststring())fmt.Println(Test2.Testint())
}

接口类型作为参数

第一点已经说了可以将实现接口的类赋值给接口,而将接口类型作为参数很常见。这时,那些实现接口的实例都能作为接口类型参数传递给函数/方法。

package mainimport ("fmt"
)// Shaper接口定义了一个名为Area的方法,该方法返回一个float64类型的值,表示形状的面积。
type Shaper interface {Area() float64
}// Circle结构体定义了一个名为radius的字段,类型为float64,表示圆的半径。
type Circle struct {radius float64
}// Circle的Area方法实现了Shaper接口中的Area方法,计算并返回圆的面积。
// 圆的面积计算公式为π乘以半径的平方。
func (c *Circle) Area() float64 {return 3.14 * c.radius * c.radius
}func main() {// 使用new函数创建Circle类型的指针类型实例c1,并初始化其值为Circle类型的零值。c1 := new(Circle)// 设置c1的radius字段值为2.5。c1.radius = 2.5// 将Circle的指针类型实例c1传给函数myArea,该函数的参数类型为Shaper接口。// 由于c1的类型实现了Shaper接口(即实现了Area方法),所以可以被传给Shaper类型的参数。myArea(c1)
}// myArea函数接受一个参数n,其类型为Shaper接口。
// 该函数调用传入的Shaper实例的Area方法,并打印出返回的面积值。
func myArea(n Shaper) {fmt.Println(n.Area())
}

多态

1、多个类型(结构体)可以实现同一个接口。
2、一个类型(结构体)可以实现多个接口。
3、实现接口的类(结构体)可以赋值给接口。

package mainimport "fmt"// Shaper接口定义了一个名为Area的方法,该方法返回一个float64类型的值,表示形状的面积。
type Shaper interface {Area() float64
}// Rectangle结构体定义了两个字段:length和width,类型均为float64,分别表示矩形的长度和宽度。
type Rectangle struct {length float64width  float64
}// Rectangle的Area方法实现了Shaper接口中的Area方法,计算并返回矩形的面积。
// 矩形的面积计算公式为长度乘以宽度。
func (r *Rectangle) Area() float64 {return r.length * r.width
}// Rectangle的Set方法是一个辅助方法,用于设置矩形的长度和宽度。
func (r *Rectangle) Set(l float64, w float64) {r.length = lr.width = w
}// Triangle结构体定义了两个字段:bottom和hight,类型均为float64,分别表示三角形的底和高。
type Triangle struct {bottom float64hight  float64
}// Triangle的Area方法实现了Shaper接口中的Area方法,计算并返回三角形的面积。
// 三角形的面积计算公式为底乘以高的一半。
func (t *Triangle) Area() float64 {return t.bottom * t.hight / 2
}// Triangle的Set方法是一个辅助方法,用于设置三角形的底和高。
func (t *Triangle) Set(b float64, h float64) {t.bottom = bt.hight = h
}func main() {// 使用new函数创建Rectangle类型的指针类型实例rect,并初始化其值为Rectangle类型的零值。rect := new(Rectangle)// 调用rect的Set方法设置矩形的长度和宽度。rect.Set(2, 3)// 将Rectangle的指针类型实例rect转换为Shaper接口类型,并存储在areaIntf变量中。// 注意:这里只能将指针类型的实例赋值给接口,因为Rectangle的Area方法是指针方法。areaIntf := Shaper(rect) //这种方法只能将指针类型的类示例赋值给接口// 使用Printf函数打印矩形的面积,格式化字符串中的%f用于占位float64类型的值。fmt.Printf("The rect has area: %f\n", areaIntf.Area())// 使用new函数创建Triangle类型的指针类型实例triangle,并初始化其值为Triangle类型的零值。triangle := new(Triangle)// 调用triangle的Set方法设置三角形的底和高。triangle.Set(2, 3)// 将Triangle的指针类型实例triangle转换为Shaper接口类型,并存储在areaIntf变量中。areaIntf = Shaper(triangle) //这种方法只能将指针类型的类示例赋值给接口// 使用Printf函数打印三角形的面积。fmt.Printf("The triangle has area: %f\n", areaIntf.Area())
}


http://www.ppmy.cn/news/1549155.html

相关文章

前端三大件之CSS

引言 CSS&#xff08;层叠样式表&#xff0c;Cascading Style Sheets&#xff09;是一种用于描述网页文档外观和格式的样式表语言。它主要用于控制网页的布局、颜色、字体、间距等视觉效果&#xff0c;使开发者能够将内容与设计分离。 一&#xff0c;CSS的基本概念 选择器&…

【Nginx从入门到精通】04-安装部署-使用XShell给虚拟机配置静态ip

文章目录 总结1、XShell &#xff1a;方便管理多台机器2、配置ip文件&#xff1a;区分大小写 一、查看上网模式二、Centos 7 设置静态ipStage 1 &#xff1a;登录root账号Stage 2 &#xff1a;设置静态ip : 修改配置文件 <font colororange>ifcfg-ens33Stage 2-1&#xf…

windows C#-异步编程概述(四)

高效等待任务 可以使用 Task 类的方法来改进上述代码末尾的一系列 await 语句。其中一个 API 是 WhenAll&#xff0c;它返回一个 Task&#xff0c;该 Task 在其参数列表中的所有任务都完成后才完成&#xff0c;如以下代码所示&#xff1a; await Task.WhenAll(eggsTask, bac…

春意盎然:基于Spring Boot的中药实验管理平台

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理中药实验管理系统的相关信息成为必然。开发…

Seatunnel解决Excel中无法将数字类型转换成字符串类型以及源码打包

需求 需要实现将Excel中的数字类型的单元格像数据库中字符串类型的字段中推送 问题原因 Seatunnel在读取字段类型的时候都是使用强转的形式去获取数据的 假如说数据类型不一样的话直接强转就会报错 修改位置 org/apache/seatunnel/api/table/type/SeaTunnelRow.java org…

linux常用命令(网络相关)

目录 1. ping - 检查网络连通性 参数 示例 2. ifconfig - 配置网络接口 参数 示例 3. ip - 显示和操作路由、网络设备、接口等 参数 示例 4. netstat - 显示网络连接、路由表、接口统计等信息 参数 示例 5. ss - 更快的netstat替代品 参数 示例 6. nslookup - …

Oracle SQL plus设置篇

安装完Oracle和db之后&#xff0c;对于Oracle的各种交互命令窗口使用起来不是很得心应手&#xff0c;上下左右键包括删除操作都需要很麻烦&#xff0c;我们可以进行一些设置使我们更丝滑的使用Oracle的各种交互命令如SQL plus、RMAN、lsnrctl等。 1. 定义别名及配置环境变量 …

PgSQL即时编译JIT | 第1期 | JIT初识

PgSQL即时编译JIT | 第1期 | JIT初识 JIT是Just-In-Time的缩写&#xff0c;也就是说程序在执行的时候生成可以执行的代码&#xff0c;然后执行它。在介绍JIT之前&#xff0c;需要说下两种执行方式&#xff1a;解释执行和编译执行。其中解释执行是通过解释器&#xff0c;将代码逐…