golang学习笔记系列之接口

接口

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

接口就像一个公司里面的领导,它会定义一些通用规范,只是设计,而不实现规范。

语法

type interface_name interface{
    func_name(parma_li)(return_li)
}
  • interface_name:接口名
  • func_name:方法名
  • param_li:参数列表
  • return_li:返回值列表
package main

import "fmt"

// 定义一个USB的读写接口
type USB interface {
	read()
	write(string)
}

// 计算机
type Computer struct {
	name string
}

//手机
type Mobile struct {
	name string
}

// 计算机实现USB接口
func (c Computer) read() {
	fmt.Printf("%v is reading...\n", c.name)
}

func (c Computer) write() {
	fmt.Printf("%v is writing...\n", c.name)
}

func main() {

	c := Computer{name: "Mac"}
	c.read()
	c.write()

}

运行结果

Mac is reading...
Mac is writing...

接口和类型的关系

  • 一个类型可以实现多个接口
  • 多个类型可以实现一个接口(多态:不同的类型调用同一个方法,具体实现细节不一样)
package main

import "fmt"

//一个类型实现多个接口
type Music interface {
	PlayMusic()
}

type Vide interface {
	PlayVideo()
}

type Mobile struct {
	name string
}

func (m Mobile) PlayMusic() {
	fmt.Printf("%v播放音乐...\n", m.name)
}

func (m Mobile) PlayVideo() {
	fmt.Printf("%v播放视频...\n", m.name)

}

// 多个类型实现一个接口
type Eat interface {
	eat()
}

type Dog struct {
	name string
}

type Cat struct {
	name string
}

func main() {

	m := Mobile{name: "Apple"}
	m.PlayMusic()
	m.PlayVideo()

	erha := Dog{name: "二哈"}
	fmt.Printf("%v is eating...\n", erha.name)
	tom := Cat{name: "Tom"}
	fmt.Printf("%v is eating...\n", tom.name)

}

运行结果

Apple播放音乐...
Apple播放视频...
二哈 is eating...
Tom is eating...

接口嵌套

接口可以通过嵌套,创建新的接口。

package main

type Fly interface {
	fly()
}

type Swim interface {
	swim()
}

type FlyFish interface {
	Fly
	Swim
}

type Fish struct {
}

func (f Fish) fly() {
	print("flying...\n")
}

func (f Fish) swim() {
	print("swimming...\n")
}

func main() {

	f := Fish{}
	f.fly()

	var ff FlyFish
	ff = Fish{}
	ff.fly()	

}

运行结果

flying...
flying...

通过接口实现开闭原则(OCP)

面向对象的可复用设计的第一块基石,便是所谓的“开闭”原则(Open-Close Principle,常缩写为OCP,意为对扩展开放,对修改关闭)。虽然go语言不是面向对象语言,但是也可以模拟实现这个原则。

package main

//定义一个宠物接口
type Pet interface {
	eat()
	sleep()
}

//定义两个结构体,然后分别实现接口
type Dog struct{}
type Cat struct{}

func (d Dog) eat() {
	print("dog is eating...\n")
}

func (d Dog) sleep() {
	print("dog is sleeping...\n")
}

func (c Cat) eat() {
	print("cat is eating...\n")
}

func (cat Cat) sleep() {
	print("cat is sleeping...\n")
}

type Person struct {
	name string
}

func (p Person) care(pet Pet) {

	pet.eat()
	pet.sleep()

}

func main() {

	d := Dog{}
	c := Cat{}
	p := Person{name: "Tom"}
	p.care(d)
	p.care(c)

}

运行结果

dog is eating...
dog is sleeping...
cat is eating...
cat is sleeping...

个人理解:为了方便理解,我觉得可以把它和面向对象语言里面的概念对比来理解,go语言中的接口有点类似于面向对象语言中的抽象基类,而实现了接口中所有方法的结构体可以看成是这个抽象基类的实现类,只有实现了接口中所有方法的实现类,才能把它看成是这个接口的一个子类,在参数类型是这个接口类型的地方,传入这个子类也是合法的。

在上面的例子中,可以看到,Pet这个接口有两个方法eat和sleep,在结构体Dog和Cat中都分别将它们实现了,因此可以将Dog和Cat看做是Pet的一个子类;而在后面的调用中也显示出了这个特性:当Person的care方法的参数是Pet类型时,传入是Dog或者Cat类型的参数也是正确的!

同时也可以举一个反例来看:

我将Cat结构体的sleep方法给注释掉,同时将p.sleep()的调用给注释掉,但是这样编译都不会通过。所以,很显然,因为Cat没有实现Pet中所有的方法,所以在使用Pet的地方是不能使用Cat的,而报错的提示也确实如此!

package main

//定义一个宠物接口
type Pet interface {
	eat()
	sleep()
}

//定义两个结构体,
type Dog struct{}
type Cat struct{}

func (d Dog) eat() {
	print("dog is eating...\n")
}

func (d Dog) sleep() {
	print("dog is sleeping...\n")
}

func (c Cat) eat() {
	print("cat is eating...\n")
}

// func (cat Cat) sleep() {
// 	print("cat is sleeping...\n")
// }

type Person struct {
	name string
}

func (p Person) care(pet Pet) {

	pet.eat()
	// pet.sleep()

}

func main() {

	d := Dog{}
	c := Cat{}
	p := Person{name: "Tom"}
	p.care(d)
	p.care(c)

}

运行结果

# command-line-arguments
./lll06_通过接口实现OCP原则.go:46:9: cannot use c (variable of type Cat) as type Pet in argument to p.care:
        Cat does not implement Pet (missing sleep method)

继承

通过结构体嵌套来实现继承。

package main

import "fmt"

//"父类"
type Pet struct {
	name string
	age  int
}

func (p Pet) eat() {
	fmt.Printf("%v is eating\n", p.name)
}

func (p Pet) sleep() {
	fmt.Printf("%v is sleeping\n", p.name)
}

// “子类”
type Dog struct {
	Pet
}

func main() {

	erha := Dog{
		Pet{name: "二哈", age: 2},
	}

	// 子类可以直接调用父类中的方法
	erha.eat()
	erha.sleep()

}

运行结果

二哈 is eating
二哈 is sleeping

同步更新于个人博客系统:golang学习笔记系列之接口

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GoLang学习笔记主要包括以下几个方面: 1. 语法规则:Go语言要求按照语法规则编写代码,例如变量声明、函数定义、控制结构等。如果程序中违反了语法规则,编译器会报错。 2. 注释:Go语言中的注释有两种形式,分别是行注释和块注释。行注释使用`//`开头,块注释使用`/*`开头,`*/`结尾。注释可以提高代码的可读性。 3. 规范代码的使用:包括正确的缩进和空白、注释风格、运算符两边加空格等。同时,Go语言的代码风格推荐使用行注释进行注释整个方法和语句。 4. 常用数据结构:如数组、切片、字符串、映射(map)等。可以使用for range遍历这些数据结构。 5. 循环结构:Go语言支持常见的循环结构,如for循环、while循环等。 6. 函数:Go语言中的函数使用`func`关键字定义,可以有参数和返回值。函数可以提高代码的重用性。 7. 指针:Go语言中的指针是一种特殊的变量,它存储的是另一个变量的内存地址。指针可以实现动态内存分配和引用类型。 8. 并发编程:Go语言提供了goroutine和channel两个并发编程的基本单位,可以方便地实现多线程和高并发程序。 9. 标准库:Go语言提供了丰富的标准库,涵盖了网络编程、文件操作、加密解密等多个领域,可以帮助开发者快速实现各种功能。 10. 错误处理:Go语言中的错误处理使用`defer`和`panic`两个关键字实现,可以有效地处理程序运行过程中出现的错误。 通过以上内容的学习,可以掌握Go语言的基本语法和编程思想,为进一步学习和应用Go语言打下坚实的基础。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Golang学习笔记](https://blog.csdn.net/weixin_52310067/article/details/129467041)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [golang学习笔记](https://blog.csdn.net/qq_44336275/article/details/111143767)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值