目录
- 1.什么是接口
- 2.接口定义
- 3.多态
- 4.接口继承与转换
- 5.空接口
- 6.接口转换
- 7.实现map字典接口
- 8.interface案例
1.什么是接口
接口就是一种规范与标准,在生活中经常见接口,例如:笔记本电脑的USB接口,可以将任何厂商生产的鼠标与键盘,与电脑进行链接。为什么呢?原因就是,USB接口将规范和标准制定好后,各个生产厂商可以按照该标准生产鼠标和键盘就可以了。
在程序开发中,接口只是规定了要做哪些事情,干什么。具体怎么做,接口是不管的。这和生活中接口的案例也很相似,例如:USB接口,只是规定了标准,但是不关心具体鼠标与键盘是怎样按照标准生产的.
在企业开发中,如果一个项目比较庞大,那么就需要一个能理清所有业务的架构师来定义一些主要的接口,这些接口告诉开发人员你需要实现那些功能。
2.接口定义
接口定义的语法如下: - 方式一:interface接收任意数据格式
- //先定义接口 一般以er结尾 根据接口实现功能
- type CurrencyEr2 interface{
- Symbol() string
- }
- 方式二:指定类型
- type Currency string
复制代码怎样具体实现接口中定义的方法呢? - func (c Currency)Symbol() string {
- m := ""
- switch c {
- case "CNY":
- // 人民币
- m = "¥"
- case "KRW":
- // 韩币
- m = "₩"
- case "TWD":
- // 台币
- m = "$"
- case "JPY":
- // 日元
- m = "¥"
- case "USD":
- // 美元
- m = "$"
- }
- return m
- }
复制代码具体的调用如下: - func main() {
- // 方式一:
- a:=CurrencyEr2(Currency("CNY")).Symbol()
- fmt.Println(a)
- // 方式二:
- b:=Currency("CNY").Symbol()
- fmt.Println(b)
- }
复制代码只要类(结构体)实现对应的接口,那么根据该类创建的对象,可以赋值给对应的接口类型。
接口的命名习惯以er结尾。
3.多态
接口有什么好处呢?实现多态。
多态就是同一个接口,使用不同的实例而执行不同操作
所谓多态指的是多种表现形式,如下图所示:
使用接口实现多态的方式如下: - package main
- import "fmt"
- //先定义接口 一般以er结尾 根据接口实现功能
- type CurrencyEr2 interface {
- //方法 方法的声明
- Symbol() string
- }
- type Currency string
- type Currency2 string
- func (c Currency) Symbol() string {
- m := ""
- switch c {
- case "CNY":
- m = "¥"
- }
- return m
- }
- func (c Currency2) Symbol() string {
- m := ""
- switch c {
- case "USD":
- m = "$"
- }
- return m
- }
- //多态的实现
- //将接口作为函数参数 实现多态
- func Start(c CurrencyEr2) string {
- return c.Symbol()
- }
- func main() {
- //调用多态函数
- a := Start(Currency("CNY"))
- fmt.Println(a)
- //调用多态函数
- b := Start(Currency2("USD"))
- fmt.Println(b)
- }
复制代码 多态加减计算器
- package main
- import "fmt"
- //定义接口
- type Opter interface {
- //方法声明
- Result() int
- }
- //父类结构体
- type Operate struct {
- num1 int
- num2 int
- }
- //加法子类结构体
- type Add struct {
- Operate
- }
- //实现加法子类的方法
- func (a *Add) Result() int {
- return a.num1 + a.num2
- }
- //减法子类结构体
- type Sub struct {
- Operate
- }
- //实现减法子类的方法
- func (s *Sub) Result() int {
- return s.num1 - s.num2
- }
- //创建一个类负责对象创建
- //工厂类
- type Factory struct {
- }
- func (f *Factory) Result(num1 int, num2 int, ch string) int {
- sum := 0
- switch ch {
- case "+":
- var a Add
- a.num1 = num1
- a.num2 = num2
- sum = Opter.Result(&a)
- case "-":
- var s Sub
- s.num1 = num1
- s.num2 = num2
- sum = Opter.Result(&s)
- }
- return sum
- }
- //通过设计模式调用
- func main() {
- //创建工厂对象
- var f Factory
- a:= f.Result(10, 20, "+")
- fmt.Println(a)
- }
复制代码 4.接口继承与转换
接口也可以实现继承: - package main
- import "fmt"
- //先定义接口 一般以er结尾 根据接口实现功能
- type Humaner2 interface { //子集
- //方法 方法的声明
- sayhi()
- }
- type Personer interface { //超集
- Humaner2 //继承sayhi()
- sing(string)
- }
- type student13 struct {
- name string
- age int
- score int
- }
- func (s *student13)sayhi() {
- fmt.Printf("大家好,我是%s,今年%d岁,我的成绩%d分\n",s.name,s.age,s.score)
- }
- func (s *student13)sing(name string) {
- fmt.Println("我为大家唱首歌",name)
- }
- func main() {
- //接口类型变量定义
- var h Humaner2
- var stu student13 = student13{"小吴",18,59}
- h = &stu
- h.sayhi()
- //接口类型变量定义
- var p Personer
- p = &stu
- p.sayhi()
- p.sing("大碗面")
- }
复制代码接口继承后,可以实现“超集”接口转换“子集”接口,代码如下: - package main
- import "fmt"
- //先定义接口 一般以er结尾 根据接口实现功能
- type Humaner2 interface { //子集
- //方法 方法的声明
- sayhi()
- }
- type Personer interface { //超集
- Humaner2 //继承sayhi()
- sing(string)
- }
- type student13 struct {
- name string
- age int
- score int
- }
- func (s *student13)sayhi() {
- fmt.Printf("大家好,我是%s,今年%d岁,我的成绩%d分\n",s.name,s.age,s.score)
- }
- func (s *student13)sing(name string) {
- fmt.Println("我为大家唱首歌",name)
- }
- func main() {
- //接口类型变量定义
- var h Humaner2 //子集
- var p Personer //超集
- var stu student13 = student13{"小吴",18,59}
- p = &stu
- //将一个接口赋值给另一个接口
- //超集中包含所有子集的方法
- h = p //ok
- h.sayhi()
- //子集不包含超集
- //不能将子集赋值给超集
- //p = h //err
- //p.sayhi()
- //p.sing("大碗面")
- }
复制代码 5.空接口
空接口(interface{})不包含任何的方法,正因为如此,所有的类型都实现了空接口,因此空接口可以存储任意类型的数值。
例如: - var i interface{}
- //接口类型可以接收任意类型的数据
- //fmt.Println(i)
- fmt.Printf("%T\n",i)
- i = 10
- fmt.Println(i)
- fmt.Printf("%T\n",i)
复制代码当函数可以接受任意的对象实例时,我们会将其声明为interface{},最典型的例子是标准库fmt中PrintXXX系列的函数,例如: - func Printf(fmt string, args ...interface{})
- func Println(args ...interface{})
复制代码如果自己定义函数,可以如下: - func Test(arg ...interface{}) {
- }
复制代码Test( )函数可以接收任意个数,任意类型的参数。
6.接口转换
结论:超集可以转换为子集,子集不可以转换为超集 - package main
- import "fmt"
- type Humaner interface { //子集
- sayhi()
- }
- type Personer interface { //超集
- Humaner //匿名字段,继承了sayhi()
- sing(lrc string)
- }
- type Student struct {
- name string
- id int
- }
- //Student实现了sayhi()
- func (tmp *Student) sayhi() {
- fmt.Printf("Student[%s, %d] sayhi\n", tmp.name, tmp.id)
- }
- func (tmp *Student) sing(lrc string) {
- fmt.Println("Student在唱着:", lrc)
- }
- func main() {
- //超集可以转换为子集,反过来不可以
- var iPro Personer //超集
- iPro = &Student{"mike", 666}
- var i Humaner //子集
- //iPro = i //err
- i = iPro //可以,超集可以转换为子集
- i.sayhi()
- }
复制代码 7.实现map字典接口
- package main
- import (
- "fmt"
- "sync"
- )
- type UserAges struct {
- ages map[string] int
- sync.Mutex
- }
- func (u *UserAges)Add(name string,age int) {
- u.Lock()
- defer u.Unlock()
- u.ages[name] = age
- }
- func (u *UserAges)Get(name string)int{
- if age,ok:=u.ages[name];ok{
- return age
- }
- return -1
- }
- func main() {
- dic:=make(map[string]int)
- dic["age"] = 18
- r:=UserAges{ages: dic}
- r.Add("jeff",20)
- fmt.Println(r)
- age:=r.Get("age")
- fmt.Println(age)
- }
复制代码 8.interface案例
- package main
- import "fmt"
- type Bike interface {
- save()
- update()
- insert()
- }
- type User struct {
- name string
- }
- func (this *User) save() {
- fmt.Println("保存成功", this.name)
- }
- func (this *User) update() {
- fmt.Println("更新成功", this.name)
- }
- func (this *User) insert() {
- fmt.Println("插入成功", this.name)
- }
- func main() {
- var data Bike = &User{name: "jeff"}
- data.save()
- data.update()
- data.insert()
- }
复制代码以上就是go语言interface接口继承多态示例及定义解析的详细内容,更多关于go语言interface接口继承多态的资料请关注晓枫资讯其它相关文章!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |