初学 Golang,对于接口部分有一些不太理解的地方,希望 V 友能帮忙解答一下。
package main
import "fmt"
type Stringer interface {
String() string
}
type Printer interface {
Stringer // 接口嵌入。
Print()
}
type User struct {
id int
name string
}
func (self *User) String() string {
return fmt.Sprintf("user %d, %s", self.id, self.name)
}
func (self *User) Print() {
fmt.Println(self.String())
}
func main() {
var t Printer = &User{1, "Tom"} // *User 方法集包含 String、Print。
// 如果去掉接口定义的代码,将上一行代码替换为下行,也可以运行,请问接口的作用体现在哪里?
// var t := User{1, "Tom"}
t.Print()
}
以上代码摘录自Go 边看边练 -《 Go 学习笔记》系列(十二)。
书上写了接口声明一个方法的签名。声明一个空方法集的接口类型,并将其作为函数参数,函数不会检查传入的是什么类型,只要这个参数满足接口定义即可,即可以通过编译器检查(个人理解)。另外,接口可以进行接口检查,接口嵌入等。我学到了这些理论知识,但对接口缺乏感性的认识。
相对于不定义接口,「直接定义结构体和结构体上的方法」的方式,额外定义了接口会带来什么好处么?
可以举几个实际的例子么?
1
gowk 2018-09-28 17:12:15 +08:00 1
接口跟语言无关,无非是为了抽象,具体说就是为了解耦,隔离变化。Go 语言中的接口跟 Java 中的大同小异,最大的区别就是 Go 语言的 Interface 是 Duck Typing,无侵入式的,另外我建议你不要用这个教程学习 Go 语言,教程里的例子为了举例而举例,对初学者而言完全没有任何意义。英文好的话直接看英文教程,推荐两本书,《 The Go Programming Language 》《 The Way To Go 》,英语对于程序员的重要性再怎么强调都不为过!
|
2
gowk 2018-09-28 17:15:44 +08:00
上面两本电子书找不到的话,可以访问我的百度网盘分享链接: https://pan.baidu.com/s/1mic0v00
里面有很多经典的计算机类的 PDF 电子书 |
3
imnotfine 2018-09-28 17:20:25 +08:00 2
其实面向对象的问题.
如果你初学编程的话, 我非常建议你跳过这部分, 因为需要你做一些项目才能理解其作用 ,特别是需要多人合作的项目 ------ 举个栗子, 如果你写了一个类, 一年后你对这个类不满意, 你想重新实现一个, 那为了保证兼容性, 你肯定不能完全写个新的对吧. 那你肯定要理清这个类提供了哪些公开的 api, 那你就得到了一个接口 然后根据这些 api 去实现一个新的类, 然后用这个新的类去替换旧代码. ------- 下面是更好的方案 那其实更好的方式是, 在刚开始写这个类的时候就想好这个类可以提供哪些方法, 然后定义一个接口, 然后一年后你写个新的, 你直接实现这个接口就好了, 而不用理清. 另外, 试想, 如果写这个新类的人是你同事, 让他去理清这些公开 api, 他应该会很头疼, 甚至直接放弃这个需求了吧. ------ 除了修改和重构上的方便外, 对调用方来说也是非常重要的, 这个涉及到多态, 然后你联想一下设计模式, 还有为什么允许`var t Printer = &User{1, "Tom"}`, 甚至推荐这种用法, 这就是你要思考的问题啦~ |
4
Deardrops OP @gowk #1 感谢解答。正在看这两本书,看到接口的部分看不大明白,谷歌到的一个解释接口的文章,顺手贴出来了。书中说,Golang 语言中接口和满足接口的类型之间没有显式的连接,有时有的自定义类型可以同时满足多个接口,使用起来不会带来困惑么?
|
5
neoblackcap 2018-09-28 17:27:24 +08:00 2
@Deardrops 这就是语言的哲学,也是面向对象的进一步理解。面向对象应该基于协议,接口。组合优先于继承,既然满足了接口,那么就应该认为这里的对象就是一类。
|
6
Deardrops OP @imnotfine #3 感谢解答。之前写过一些 JS,对 OOP 一直没啥概念,听了你的解释明白了很多东西。谢谢!
|
7
tourist2018 2018-09-28 17:38:15 +08:00
golang 的接口就是一系列方法的集合
|
8
misaka19000 2018-09-28 17:44:51 +08:00
我也是在了解了 golang 的接口之后才对计算机里面的指令和数据有了更进一步的了解
|
9
gamexg 2018-09-28 20:58:03 +08:00 1
实际使用下 go 的压缩、加密库就能够理解接口的作用了。
加密、压缩传入 Writer 接口,输出的还是兼容 Writer,只要需求方实现了 Write 方法都能使用,不用管是文件还是连接。 |
10
owenliang 2018-09-29 09:52:39 +08:00
面向接口编程啊,无论是过程式的还是对象式的,都可以实现接口和实现的分离。
|
11
hijoker 2018-09-30 14:11:57 +08:00
感觉卵用没有,没有默认的接口实现
|