目录

  • 接口介绍与定义
  • 空接口和类型断言
  • 指针接收和值接收区别
  • 接口嵌套

接口介绍与定义

1、 接口定义了一个对象的行为规范

A. 只定义规范,不实现
B. 具体的对象需要实现规范的细节

2、Go中接口定义

A. type 接口名字 interface
B. 接口里面是一组方法签名的集合

type Animal interface {
Talk()
Eat() int
Run()
}

  

3、Go中接口的实现

A. 一个对象只要包含接口中的方法,那么就实现了这个接口
B. 接口类型的变量可以保存具体类型的实例

type Animal interface {
Talk()
Eat() int
Run()
}

  

4、接口实例

A. 一个公司需要计算所有职员的薪水
B. 每个职员的薪水计算方式不同

package main

import (
"fmt"
) type Employer interface {
CalcSalary() float32
} type Programer struct {
name string
base float32
extra float32
} func NewProgramer(name string, base float32, extra float32) Programer {
return Programer{
name: name,
base: base,
extra: extra,
}
} func (p Programer) CalcSalary() float32 {
return p.base
} type Sale struct {
name string
base float32
extra float32
} func NewSale(name string, base, extra float32) Sale {
return Sale{
name: name,
base: base,
extra: extra,
}
} func (p Sale) CalcSalary() float32 {
return p.base + p.extra*p.base*0.5
} func calcALL(e []Employer) float32 {
var cost float32
for _, v := range e {
cost = cost + v.CalcSalary()
} return cost
} func main() {
p1 := NewProgramer("搬砖1", 1500.0, 0)
p2 := NewProgramer("搬砖2", 1500.0, 0)
p3 := NewProgramer("搬砖3", 1500.0, 0) s1 := NewSale("销售1", 800.0, 2.5)
s2 := NewSale("销售2", 800.0, 2.5)
s3 := NewSale("销售3", 800.0, 2.5) var employList []Employer
employList = append(employList, p1)
employList = append(employList, p2)
employList = append(employList, p3) employList = append(employList, s1)
employList = append(employList, s2)
employList = append(employList, s3) cost := calcALL(employList)
fmt.Printf("这个月的人力成本:%f\n", cost) }

  

5、接口类型变量

A. var a Animal
B. 那么a能够存储所有实现Animal接口的对象实例

package main

import "fmt"

type Animal interface {
Talk()
Eat()
Name() string
} type Dog struct {
} func (d Dog) Talk() {
fmt.Println("汪汪汪")
} func (d Dog) Eat() {
fmt.Println("我在吃骨头")
} func (d Dog) Name() string {
fmt.Println("我的名字叫旺财")
return "旺财"
} type Pig struct {
} func (d Pig) Talk() {
fmt.Println("坑坑坑")
} func (d Pig) Eat() {
fmt.Println("我在吃草")
} func (d Pig) Name() string {
fmt.Println("我的名字叫八戒")
return "八戒"
} func testInterface1() {
var d Dog
var a Animal
a = d a.Eat()
a.Talk()
a.Name() var pig Pig
a = pig
a.Eat()
a.Talk()
a.Name()
} func just(a Animal) {
// d, ok := a.(Dog)
// p, ok := a.(Pig)
switch v := a.(type) {
case Dog:
fmt.Printf("v is dog, %v\n", v)
case Pig:
fmt.Printf("v is dog, %v\n", v)
default:
fmt.Printf("not support")
}
} func testInterface2() {
var d Dog
just(d)
} func main() {
//testInterface1()
testInterface2()
}

  

空接口和类型断言

1、空接口

A. 空接口没有定义任何方法
B. 所以任何类型都实现了空接口

interface {
}

  

package main

import "fmt"

func describe(a interface{}) {
fmt.Printf("%T %v\n", a, a)
} func testInterface() {
var a interface{}
var b int = 100
a = b fmt.Printf("%T %v\n", a, a) var c string = "hello"
a = c
fmt.Printf("%T %v\n", a, a) var d map[string]int = make(map[string]int, 100)
d["abc"] = 1000
d["eke"] = 30 a = d
fmt.Printf("%T %v\n", a, a)
} type Student struct {
Name string
Sex int
} func main() { a := 65
describe(a) str := "hello"
describe(str) var stu Student = Student{
Name: "user01",
Sex: 1,
} describe(stu)
}

  

2、类型断言

A. 如何获取接口类型里面存储的具体的值呢?

B.类型断言的坑

C.如何解决,引入 ok判断机制! v, ok := i.(T)

D.type switch。

E.type switch另外一种写法,解决转两次的问题

package main

import "fmt"

// 类型断言
func test(a interface{}) {
s, ok := a.(int)
if ok {
fmt.Println(s)
return
}
str, ok := a.(string)
if ok {
fmt.Println(str)
return
} f, ok := a.(float32)
if ok {
fmt.Println(f)
return
} fmt.Println("can not define the type of a") } func testInterface1() {
var a int = 100
test(a) var b string = "hello"
test(b)
} // case优雅实现(二次转换)
func testSwitch(a interface{}) {
switch a.(type) {
case string:
fmt.Printf("a is string, value: %v", a.(string))
case int:
fmt.Printf("a is int, value: %v", a.(int))
case int32:
fmt.Printf("a is not, value: %v", a.(int32))
default:
fmt.Println("no support type")
}
} func testInterface2() {
var a int = 100
testSwitch(a) var b string = "hellow"
testSwitch(b)
} // case优雅实现(一次转换)
func testSwitch2(a interface{}) {
switch v := a.(type) {
case string:
fmt.Printf("a is string, value: %v", v)
case int:
fmt.Printf("a is int, value: %v", v)
case int32:
fmt.Printf("a is not, value: %v", v)
default:
fmt.Println("no support type")
}
} func testInterface3() {
var a int = 100
testSwitch2(a) var b string = "hellow"
testSwitch2(b)
} func main() {
testInterface1()
testInterface2()
testInterface3()
}

  

指针接收和值接收区别

1、指针接收

package main

import "fmt"

type Animal interface {
Talk()
Eat()
Name() string
} type Dog struct {
} func (d *Dog) Talk() {
fmt.Println("汪汪汪")
} func (d *Dog) Eat() {
fmt.Println("我在吃骨头")
} func (d *Dog) Name() string {
fmt.Println("我的名字叫旺财")
} func main() {
var a Animal
// 值
// a存的是一个值类型的Dog,那么调用a.Eat(). &Dog ->Eat()
// 如果一个变量存储在接口类型的变量中之后,那么不能获取这个变量的地址
//var d Dog
//a = d
//a.Eat()
//
//fmt.Printf("%T %v\n", a, a) // 指针
var d1 *Dog = &Dog{}
a = d1
// *(&Dog).Eat()
a.Eat()
fmt.Printf("*Dog %T %v\n", d1, d1)
}

  

接口嵌套

1、 实现多接口,同一个类型可以实现多个接口

2、 接口嵌套,和结构体嵌套类似

package main

import "fmt"

type Animal interface {
Talk()
Eat()
Name() string
} type PuruDongwu interface {
TaiSheng()
} type Dog struct {
} func (d Dog) Talk() {
fmt.Println("汪汪汪")
} func (d Dog) Eat() {
fmt.Println("我在吃骨头")
} func (d Dog) Name() string {
fmt.Println("我的名字叫旺财")
return "旺财"
} func (d Dog) TaiSheng() {
fmt.Println("狗是胎生的")
} func main() {
var d Dog
var a Animal fmt.Printf("%v %T %p", a, a, a) if a == nil {
fmt.Println("a is nil")
} a = d
a.Eat() var b PuruDongwu
b = d
b.TaiSheng()
}

  

【原创】go语言学习(十六)接口的更多相关文章

  1. Go语言学习笔记六: 循环语句

    Go语言学习笔记六: 循环语句 今天学了一个格式化代码的命令:gofmt -w chapter6.go for循环 for循环有3种形式: for init; condition; increment ...

  2. 强化学习(十六) 深度确定性策略梯度(DDPG)

    在强化学习(十五) A3C中,我们讨论了使用多线程的方法来解决Actor-Critic难收敛的问题,今天我们不使用多线程,而是使用和DDQN类似的方法:即经验回放和双网络的方法来改进Actor-Cri ...

  3. 【原创】go语言学习(六)函数详解2

    目录 变量作用域和可见性 匿名函数 闭包 课后练习 变量作用域和可见性 1.全局变量量,在程序整个生命周期有效. var a int = 10 2.局部变量量,分为两种: 1)函数内定义, 2)语句句 ...

  4. Dart语言学习(十二) Dart面向对象

    Dart作为一种高级语言,支持面向对象的很多特性,并且支持基于mixin的继承方式. 基于mixin的继承方式是指:一个类可以继承自多个父类,相当于其他语言里的多继承. 所有的类都有同一个基类Obje ...

  5. Dart语言学习(十) Dart流程控制语句

    一.条件语句:if.if...elseif.if...elseif...else int score = 95; if (score >=90) { print('优秀'); } else if ...

  6. C 语言学习 第六次作业总结

    本次作业,同学们开始学习函数.通过之前和同学们的沟通,似乎同学们在这里遇到的问题比较多.下面,我先帮同学们整理下函数的相关知识点. 什么是函数 首先,需要明确的是,什么是函数.所谓函数,也就是一段有名 ...

  7. C语言学习第六章

    今天开始尝试改变! 今天要学习函数,一个C语言中的重要组成部分. 首先先聊聊为什么要使用函数?随着学习的深入很多人会发现某段的代码重复使用的几率很大,而如果用一次写一次的话很明显的效率就会比较低,如果 ...

  8. Go语言学习之7 接口实例、终端文件读写、异常处理

    本节主要内容: 1. 终端读写2. 文件读写3. 命令行参数4. Json5. 自定义错误 1. 终端读写 操作终端相关文件句柄常量    os.Stdin:标准输入    os.Stdout:标准输 ...

  9. GO语言学习(六)Go 语言数据类型

    在 Go 编程语言中,数据类型用于声明函数和变量. 数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存. Go 语言按类别有以下几种 ...

  10. Go语言学习笔记(9)——接口类型

    接口 Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口. /* 定义接口 */ type interface_name in ...

随机推荐

  1. 【Linux】Shell批量修改文件名

    修改文件名,替换中间字符: 例如:ABC_define_EFG.jpg,要把中间的define替换成argument: 用如下脚本即可: for var in *; do mv "$var& ...

  2. [Luogu5280][ZJOI2019]线段树(线段树+DP)

    https://www.luogu.org/blog/Sooke/solution-p5280 首先想到对线段树上每个点分别维护有多少棵线段树在它上有标记(f[]),然后想到对于每个操作,根据转移的不 ...

  3. hdu 2132... 被基本问题考住了。。

    Problem Description We once did a lot of recursional problem . I think some of them is easy for you ...

  4. Python遗传和进化算法框架(一)Geatpy快速入门

    https://blog.csdn.net/qq_33353186/article/details/82014986 Geatpy是一个高性能的Python遗传算法库以及开放式进化算法框架,由华南理工 ...

  5. linux Ubuntu14.04 make编译文件报错:No rule to make target `/usr/lib/libpython2.7.so', needed by `python/_pywraps2.so'. Stop.

    错误过程:当“make”编译文件时报错No rule to make target `/usr/lib/libpython2.7.so', needed by `python/_pywraps2.so ...

  6. 同步IO,异步IO,阻塞,非阻塞的定义与区别

    异步I/O 是指用户程序发起IO请求后,不等待数据,同时操作系统内核负责I/O操作把数据从内核拷贝到用户程序的缓冲区后通知应用程序.数据拷贝是由操作系统内核完成,用户程序从一开始就没有等待数据,发起请 ...

  7. 命令“regsvr32 /s /n /i:user "XXXXXX"”已退出,代码为 3

    问题:命令“regsvr32 /s /n /i:user "F:\XXXXXXXXXXXXXXXXX\Release\One.ocx"”已退出,代码为 3 解决方法: The is ...

  8. 记一次bypass某场景GD库及拓展分析

    0x00 前言 gou楼兰师傅发来个站说是过不了gd库,问我有啥办法没有,给了他之前海贼师傅说的jpg_payload脚本,但是绕不过,问他拿了站点,写了个jpg_payload批量的fuzz脚本,f ...

  9. 华为SDN:解决传统网络3大问题

    转:http://mp.ofweek.com/tele/a145613326756 科技潮人 2013-08-05 14:20 传统网络之困 互联网爆炸式增长,除了规模和发展速度远超之前所有曾出现的数 ...

  10. RHEL/CentOS/Fedora各种源(EPEL、Remi、RPMForge、RPMFusion)

    参考:RHEL/CentOS/Fedora各种源(EPEL.Remi.RPMForge.RPMFusion)配置 简介 CentOS 默认自带 CentOS-Base.repo 源, 但官方源中去除了 ...