在Python中,为了对一类事务进行抽象描述,引入了class类这个概念。即拥有相同属性和方法的事务都成为一个类。以我们常见的电脑(computer)为例。电脑是一个类的名称,所有的电脑都有相同的属性如电脑名称,也拥有相同的使用方法如开机、关机等。那么用Python语言描述的话,示例代码如下

class Computer:
def __init__(self, computer_type):
# 描述基础属性 电脑类型
self.computer_type = computer_type

def poweron(self):
print("{} 开机".format(self.computer_type))

def poweroff(self):
print("{} 关机".format(self.computer_type))


lap = Computer("laptop")
desk = Computer("desktop")

lap.poweron()
desk.poweroff()

运行结果

% python main.py
laptop 开机
desktop 关机

在golang中,没有"类class"的。但是Go通过stuct把接口和方法串联起来,在Go中使用interface接口来实现"类"这种抽象的效果。interface在Golang中是一种数据类型(与string,int一样)。但是它比较特殊,只有在结构体struct的配合下,完全实现声明中方法method,才被认可实现了接口。

package main

import "fmt"

// 定义一个接口("类"),以及这个接口内部可调用的<方法>
type Computer interface {
//方法的名称、参数以及返回值类型
PowerOn() string
PowerOff() string
}

// 定义一个结构体,描述接口("类")的属性字段
type ClassSelf struct {
ComputerType string
}

// 正常的函数名称前面加一个"()" ,这个括号前面的括号叫做接收器
func (c ClassSelf) PowerOn() string {
ret := fmt.Sprintf("%s 开机", c.ComputerType)
return ret
}

// 在接收器里将结构体<Computer>实例传入,这个函数这时候就实现了interface中的描述的<方法>
func (c ClassSelf) PowerOff() string {
ret := fmt.Sprintf("%s 关机", c.ComputerType)
return ret
}

// interface也是一种数据类型,可以作为函数的变量使用
// 体现interface的约束作用
func TestInterface(i Computer) {
fmt.Println(i.PowerOn())
fmt.Println(i.PowerOff())
}

func main() {
// 结构体实例化
var lap ClassSelf
lap.ComputerType = "laptop"

var desk ClassSelf
desk.ComputerType = "Desktop"

// 结构体实例化以后,就可以调用<接收这个结构体为属性的方法>了,
// 相当于验证两个接口必须的方法没问题
//fmt.Println(lap.PowerOn())
//fmt.Println(desk.PowerOff())

// 因为结构体ClassSelf 实现了接口要求方法。
//所以实例化的结构体类型的变量,可以被当做Computer接口类型传入函数
TestInterface(lap)
TestInterface(desk)

}

运行结果

% go run main.go
laptop 开机
laptop 关机
Desktop 开机
Desktop 关机


如果不能完全实现接口的方法

package main

import "fmt"

// 定义一个接口("类"),以及这个接口内部可调用的<方法>
type Computer interface {
//方法的名称、参数以及返回值类型
PowerOn() string
PowerOff() string
}

// 定义一个iphone的结构体
type IPhone struct {
ComputerType string
}

// 接收iphone结构体,只实现了一个开机的方法
func (iphone IPhone) PowerOn() string {
ret := fmt.Sprintf("%s 开机", c.ComputerType)
return ret
}

// 验证interface的限制
func TestInterface(i Computer) {
fmt.Println(i.PowerOn())
fmt.Println(i.PowerOff())
}

func main() {
// 结构体实例化
var p IPhone
p.ComputerType = "iphone"
// 尝试传入未完全实现强制方法的struct
TestInterface(p)

}

运行结果,直接报错。提示IPhone结构体没有实现PowerOff方法

% go run main.go
# command-line-arguments
./main.go:19:34: undefined: c
./main.go:33:16: cannot use p (variable of type IPhone) as type Computer in argument to TestInterface:
IPhone does not implement Computer (missing PowerOff method)