Bruce Blog Bruce Blog
首页
  • CentOS
  • Ubuntu-Debian
  • 系统网络
  • 系统辅助工具
  • MySQL
  • Redis
  • Mongodb
  • Docker基础
  • Container基础
  • Kubernetes

    • Kubernetes基础
    • Kubernetes辅助
  • Container-Network
  • Jenkins
  • Gitlab
  • ArgoCD
  • Ansible
  • Terraform
  • AWS
  • MQ
  • NGINX
  • JumpServer
  • 基础
  • 函数模块
  • 框架
  • 基础

    • Golang环境
    • 语法
    • 数据类型与运算符
    • 分支语句
    • 循环语句
    • 数组
    • 切片
    • Map
    • String
    • 函数
    • 包的管理
    • 指针
    • 结构体
    • Go语言中的OOP
    • 方法和接口
    • 错误处理
  • Go进阶

    • Go进阶
  • Go框架

    • Go框架
  • Golang辅助

    • Golang辅助
  • CSS
  • HTML
  • JavaScript
  • 前端辅助
  • 常用命令
  • 性能监控工具
  • Windows下Docker使用
  • 日常学习
  • 其他导航

Bruce Tao

运维界的该溜子
首页
  • CentOS
  • Ubuntu-Debian
  • 系统网络
  • 系统辅助工具
  • MySQL
  • Redis
  • Mongodb
  • Docker基础
  • Container基础
  • Kubernetes

    • Kubernetes基础
    • Kubernetes辅助
  • Container-Network
  • Jenkins
  • Gitlab
  • ArgoCD
  • Ansible
  • Terraform
  • AWS
  • MQ
  • NGINX
  • JumpServer
  • 基础
  • 函数模块
  • 框架
  • 基础

    • Golang环境
    • 语法
    • 数据类型与运算符
    • 分支语句
    • 循环语句
    • 数组
    • 切片
    • Map
    • String
    • 函数
    • 包的管理
    • 指针
    • 结构体
    • Go语言中的OOP
    • 方法和接口
    • 错误处理
  • Go进阶

    • Go进阶
  • Go框架

    • Go框架
  • Golang辅助

    • Golang辅助
  • CSS
  • HTML
  • JavaScript
  • 前端辅助
  • 常用命令
  • 性能监控工具
  • Windows下Docker使用
  • 日常学习
  • 其他导航
  • 基础

    • Golang环境

    • 语法

    • 数据类型与运算符

    • 分支语句

    • 循环语句

    • 数组

    • 切片

    • Map

    • String

    • 函数

    • 包的管理

    • 指针

    • 结构体

    • Go语言中的OOP

    • 方法和接口

      • 方法和接口
      • 方法
      • 接口
        • 接口嵌套
        • 接口断言
        • type关键字
      • 错误处理

    • Go进阶

    • Go框架

    • Golang辅助

    • Golang
    • 基础
    • 方法和接口
    Bruce
    2022-10-27
    目录

    接口

    # 接口

    # 1.1 什么是接口?

    • 面向对象世界中的接口的一般定义是“接口定义对象的行为”.它表示让指定对象应该做什么.实现这种行为的方法(实现细节)是针对对象的.
    • 在Go中,接口是一组方法签名.当类型为接口中的所有方法提供定义时,它被称为实现接口.它与OOP非常相似.接口指定了类型应该具有的方法,类型决定了如何实现这些方法.

    它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口

    接口定义了一组方法,如果某个对象实现了某个接口的所有方法,则此对象就实现了该接口.

    # 1.2 接口的定义语法

    # 定义接口
    /* 定义接口 */
    type interface_name interface {
       method_name1 [return_type]
       method_name2 [return_type]
       method_name3 [return_type]
       ...
       method_namen [return_type]
    }
    
    /* 定义结构体 */
    type struct_name struct {
       /* variables */
    }
    
    /* 实现接口方法 */
    func (struct_name_variable struct_name) method_name1() [return_type] {
       /* 方法实现 */
    }
    ...
    func (struct_name_variable struct_name) method_namen() [return_type] {
       /* 方法实现*/
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    示例代码:

    package main
    
    import (
        "fmt"
    )
    
    type Phone interface {
        call()
    }
    
    type NokiaPhone struct {
    }
    
    func (nokiaPhone NokiaPhone) call() {
        fmt.Println("I am Nokia, I can call you!")
    }
    
    type IPhone struct {
    }
    
    func (iPhone IPhone) call() {
        fmt.Println("I am iPhone, I can call you!")
    }
    
    func main() {
        var phone Phone
    
        phone = new(NokiaPhone)
        phone.call()
    
        phone = new(IPhone)
        phone.call()
    
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34

    运行结果:

    I am Nokia, I can call you!
    I am iPhone, I can call you!
    
    1
    2
    • interface可以被任意的对象实现
    • 一个对象可以实现任意多个interface
    • 任意的类型都实现了空interface(这样定义:interface{}),也就是包含0个method的interface

    # 1.3 interface值

    package main
    
    import "fmt"
    
    type Human struct {
    	name  string
    	age   int
    	phone string
    }
    type Student struct {
    	Human  //匿名字段
    	school string
    	loan   float32
    }
    type Employee struct {
    	Human   //匿名字段
    	company string
    	money   float32
    } //Human实现Sayhi方法
    func (h Human) SayHi() {
    	fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
    } //Human实现Sing方法
    func (h Human) Sing(lyrics string) {
    	fmt.Println("La la la la...", lyrics)
    } //Employee重写Human的SayHi方法
    func (e Employee) SayHi() {
    	fmt.Printf("Hi, I am %s, I work at %s. Call me on %s\n", e.name,
    		e.company, e.phone) //Yes you can split into 2 lines here.
    }
    
    // Interface Men被Human,Student和Employee实现
    // 因为这三个类型都实现了这两个方法
    type Men interface {
    	SayHi()
    	Sing(lyrics string)
    }
    
    func main() {
    	mike := Student{Human{"Mike", 25, "222-222-XXX"}, "MIT", 0.00}
    	paul := Student{Human{"Paul", 26, "111-222-XXX"}, "Harvard", 100}
    	sam := Employee{Human{"Sam", 36, "444-222-XXX"}, "Golang Inc.", 1000}
    	Tom := Employee{Human{"Sam", 36, "444-222-XXX"}, "Things Ltd.", 5000}
    	//定义Men类型的变量i
    	var i Men
    	//i能存储Student
    	i = mike
    	fmt.Println("This is Mike, a Student:")
    	i.SayHi()
    	i.Sing("November rain")
    	//i也能存储Employee
    	i = Tom
    	fmt.Println("This is Tom, an Employee:")
    	i.SayHi()
    	i.Sing("Born to be wild")
    	//定义了slice Men
    	fmt.Println("Let's use a slice of Men and see what happens")
    	x := make([]Men, 3)
    	//T这三个都是不同类型的元素,但是他们实现了interface同一个接口
    	x[0], x[1], x[2] = paul, sam, mike
    	for _, value := range x {
    		value.SayHi()
    	}
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63

    运行结果:

    	This is Mike, a Student:
    	Hi, I am Mike you can call me on 222-222-XXX
    	La la la la... November rain
    	This is Tom, an Employee:
    	Hi, I am Sam, I work at Things Ltd.. Call me on 444-222-XXX
    	La la la la... Born to be wild
    	Let's use a slice of Men and see what happens
    	Hi, I am Paul you can call me on 111-222-XXX
    	Hi, I am Sam, I work at Golang Inc.. Call me on 444-222-XXX
    	Hi, I am Mike you can call me on 222-222-XXX
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    那么interface里面到底能存什么值呢?如果定义了一个interface的变量,那么这个变量里面可以存实现这个interface的任意类型的对象.例如上面例子中,定义了一个Men interface类型的变量m,那么m里面可以存Human、Student或者Employee值

    当然,使用指针的方式,也是可以的

    但是,接口对象不能调用实现对象的属性

    # interface函数参数
    • interface的变量可以持有任意实现该interface类型的对象,这给编写函数(包括method)提供了一些额外的思考,是不是可以通过定义interface参数,让函数接受各种类型的参数
    # 嵌入interface
    package main
    
    import "fmt"
    
    type Human interface {
    	Len()
    }
    type Student interface {
    	Human
    }
    
    type Test struct {
    }
    
    func (h *Test) Len() {
    	fmt.Println("成功")
    }
    func main() {
    	var s Student
    	s = new(Test)
    	s.Len()
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    示例代码:

    package test
    
    import (
    	"fmt"
    )
    
    type Controller struct {
    	M int32
    }
    
    type Something interface {
    	Get()
    	Post()
    }
    
    func (c *Controller) Get() {
    	fmt.Print("GET")
    }
    
    func (c *Controller) Post() {
    	fmt.Print("POST")
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    package main
    
    import (
    	"fmt"
    	"test"
    )
    
    type T struct {
    	test.Controller
    }
    
    func (t *T) Get() {
    	//new(test.Controller).Get()
    	fmt.Print("T")
    }
    func (t *T) Post() {
    	fmt.Print("T")
    }
    func main() {
    	var something test.Something
    	something = new(T)
    	var t T
    	t.M = 1
    	//	t.Controller.M = 1
    	something.Get()
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    • Controller实现了所有的Something接口方法,当结构体T中调用Controller结构体的时候,T就相当于Java中的继承,T继承了Controller,因此,T可以不用重写所有的Something接口中的方法,因为父构造器已经实现了接口.
    • 如果Controller没有实现Something接口方法,则T要调用Something中方法,就要实现其所有方法.
    • 如果something = new(test.Controller)则调用的是Controller中的Get方法.
    • T可以使用Controller结构体中定义的变量

    # 总结

    • 接口对象不能调用接口实现对象的属性
    上次更新: 2024/04/09, 16:48:42
    方法
    接口嵌套

    ← 方法 接口嵌套→

    最近更新
    01
    AWS NAT-NetWork-Firwalld配置(一)
    04-09
    02
    AWS NAT-NetWork-Firwalld配置(二)
    04-09
    03
    kubernetes部署minio对象存储
    01-18
    更多文章>
    Theme by Vdoing | Copyright © 2019-2024 Bruce Tao Blog Space | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式