Go语言struct与interface及Goland使用技巧

开发工具:Goland

示例代码

package main

import "fmt"

type Computer interface {
	Calculator
	Play(string) string
}

type Calculator interface {
	Open(string) Calculator
	Say() string
	Add(uint, uint)
	Sum(int, int) int
}

type TOM struct {
	Name string
	Age  int
	Bob  *BOB
}

type BOB struct {
	TOM
	MyName string
}

func (t *TOM) Open(s string) Calculator {
	return t
}

func (t *TOM) Say() string {
	return "I am " + t.Name
}

func (t *TOM) Add(a, b uint) {
	fmt.Println(a + b)
}

func (t *TOM) Sum(a, b int) int {
	return a + b
}

func (t *TOM) Play(s string) string {
	return s
}

func (b *BOB) Say() string {
	return "My Name is " + b.MyName
}

func main() {
	b := new(BOB)
	b.MyName = "Bob"
	t := new(TOM)
	t.Name = "Tom"
	t.Age = 12
	fmt.Println(t.Say())
}

一个struct(结构体)如何实现一个interface(接口)

在Go语言中,一个struct实现了某个接口里的所有方法,叫做这个struct实现了该接口。
比如上面的例子中,接口Calculator中共有四个方法

Open(string) Calculator
Say() string
Add(uint, uint)
Sum(int, int) int

而结构体TOM必须要实现这全部4个方法,才叫做结构体BOB实现了Calculator接口,Go语言struct与interface及Goland使用技巧_第1张图片
在Goland编译器中,如果一个结构体实现了某个接口,这个结构体的源码旁边就会显示接口实现标记,在这里插入图片描述
一个绿底色的,旁边一个向上的红色箭头↑,点击这个标记,就能看到该结构体实现了哪些类,Go语言struct与interface及Goland使用技巧_第2张图片
如果TOM只实现了三个方法,那TOM就没有实现Calculator接口,而Goland工具上也不会显示这个标记
接口实现标记
而如果一个接口里的【所有方法】,都被某个struct实现了,那么这个接口的源码旁边也同样会被标记,有struct实现了这个接口,
在这里插入图片描述
一个绿底色的,和一个向下的黑箭头↓,点击这个标志,就能看到哪些struct实现了这个interface,
Go语言struct与interface及Goland使用技巧_第3张图片
然后点击struct,就能查看这些struct的源码定义。

struct(结构体)嵌套

当一个结构体A将另一个结构体B作为其中一个字段时(仅将结构体作为字段;而不是声明一个变量,其类型为结构体B),结构体A就可以直接调用结构体B所绑定的方法,同时也拥有了结构体B中的字段(变量);如果结构体B实现了某个接口E,那么,此时,结构体A也自动实现了接口E
比如上面例子中,结构体TOM是结构体BOB中的一个字段,所以结构体BOB并没有全部绑定接口Calculator中的四个方法,但是可以看到结构体BOB也实现了接口CalculatorGo语言struct与interface及Goland使用技巧_第4张图片
不过这里要注意的是,BOBTOM本身作为一个字段,
Go语言struct与interface及Goland使用技巧_第5张图片
而不是定义一个变量,该变量的类型是TOM
Go语言struct与interface及Goland使用技巧_第6张图片
TOM作为变量t的类型,这种情况,结构体BOB就不能直接调用TOM所绑定的方法,结构体BOB也就没有实现接口CalculatorGo语言struct与interface及Goland使用技巧_第7张图片
结构体BOB只能调用变量t,然后用变量t来调用TOM所绑定的方法。

方法重写

示例代码

package main

import "fmt"

type TOM struct {
	Name string
	Age  int
	Bob  *BOB
	n    int
}

type BOB struct {
	TOM
	MyName string
}

func (t *TOM) Open(s string)  {
}

func (t *TOM) Say(string) string {
	return "I am " + t.Name
}

func (t *TOM) Add(a, b uint) {
	fmt.Println(a + b)
}

func (t *TOM) Sum(a, b int) int {
	return a + b
}

func (t *TOM) Play(s string) string {
	return s
}

func (b *BOB) Say(string) string {
	return "My Name is " + b.MyName
}

func main() {
	b := new(BOB)
	b.MyName = "Bob"
	fmt.Println(b.n)
	t := new(TOM)
	t.Name = "Tom"
	t.Age = 12
	fmt.Println(t.Say(""))
}

这个例子中结构体BOBTOM本身作为字段的时候,BOB就可以直接调用TOM中所有的变量(包括小写字母开头的私有变量),和所有的方法,我们把这种情况叫做【继承】(暂且叫做继承吧)。
结构体BOB继承了TOM,此时结构体BOB已经可以直接调用TOM绑定的所有方法了,但是BOB自己又绑定了一个与TOM的某个方法的方法名相同、参数相同,返回值类型也相同的一个方法Say(),这种情况,叫做【方法重写】。
意思就是结构体BOB重写了结构体TOM绑定的方法Say(),内部做了与之前TOM所绑定的Say()方法不同的处理。
在Goland编译器中,当一个struct的某个方法被重写的时候,这个方法的旁边会有一个方法重写的提示,
在这里插入图片描述
一个蓝底色的圆圈,和一个向下的黑色箭头,在这里插入图片描述
这个标志,表示该方法被重写,点击这个标志,就可以查看哪个struct重写了该方法,Go语言struct与interface及Goland使用技巧_第8张图片
再点击这个弹出来的struct,就可以看到被重写后的方法,
相应的,如果一个方法重写了某个方法,Goland也会有提示,Go语言struct与interface及Goland使用技巧_第9张图片
一个蓝底色的圆圈,和一个向上的红色箭头↑,在这里插入图片描述
代表该方法重写了另一个方法,点击这个标志,就可以直接跳到原来的方法上
当一个结构体A重写了结构体B的方法,在调用时,结构体A会调用自己所绑定的方法,也就是被A重写后的方法,而结构体B只能调用自己原来的方法,也就是重写前的方法;
不过A也可以调用重写前的方法,但是要通过B来调用,也就是A调用字段B,再调用原来的方法。Go语言struct与interface及Goland使用技巧_第10张图片
可以看到这里的Say()方法是被结构体BOB绑定的,
而在调了TOM后,也可以调用Say()方法,不过此时调用的Say()是被TOM绑定的。
Go语言struct与interface及Goland使用技巧_第11张图片

最后再说说Go语言里面的实现方法,一个结构体要实现一个接口,就要实现这个接口里的所有方法,这里的实现是指,给该结构体绑定与接口里的方法声明完全相同的方法,即方法名相同(包括大小写相同),参数类型和参数个数相同,返回值个数和类型也相同。

你可能感兴趣的:(go语言)