本想配个图,懒得找了
还是得配一个
嗯,的确是跟风学的golang
golang的接口同样没有显示的申明字段,只要实现了接口的所有方法(实现类型的方法定义与接口完全一致)即为实现该接口
package main
import "fmt"
//Animal Animal
type Animal interface {
Show()
}
//Cat Cat
type Cat struct {
Name string
}
//Show Show
func (c Cat) Show() {
fmt.Println(c)
}
//TShow TShow
func TShow(a Animal) {
a.Show()
}
func main() {
//接口不是具体类型,不能实例化
// an := Animal{}
//go中面向对象的多态特性是由接口来实现
var animal Animal = Cat{"cc-cat"}
TShow(animal)
cat := Cat{"cat"}
TShow(cat)
//同样 指针也会进行相应的转换
TShow(&cat)
}
接口可以继承接口,实现类型能实现多种接口
package main
import "fmt"
//Aerocraft 飞行器
type Aerocraft interface {
Fly()
}
//Submersible 潜水器
type Submersible interface {
Dive()
}
//SpecialMachines Special machines
type SpecialMachines struct {
Name string
}
//Fly Fly
func (m SpecialMachines) Fly() {
fmt.Println(m, "is flying...")
}
//Dive Dive
func (m SpecialMachines) Dive() {
fmt.Println(m, "is diving...")
}
//TestFly TestFly
func TestFly(aerocraft Aerocraft) {
aerocraft.Fly()
}
//TestDive dive
func TestDive(submersible Submersible) {
submersible.Dive()
}
//Airplane airplane
type Airplane interface {
Aerocraft
ShowBrand()
}
//Boeing boeing
type Boeing struct {
Brand string
}
//ShowBrand showbrand
func (b Boeing) ShowBrand() {
fmt.Println("aerocraft brand --->", b.Brand)
}
//Fly fly
func (b Boeing) Fly() {
fmt.Println("boeing fly...")
}
//PrintBrand PrintBrand
func PrintBrand(a Airplane) {
a.ShowBrand()
}
func main() {
//实现多接口
smachines := SpecialMachines{"special-machines"}
TestFly(smachines)
TestDive(smachines)
//接口继承 实现接口就必须实现该接口继承接口的所有方法
boeing := Boeing{"boeing-747"}
TestFly(boeing)
PrintBrand(boeing)
}
标题其实有点不准确,golang中只要是自定义类型,就可以实现接口,而不仅仅是结构体struct
package main
import (
"fmt"
"go_code/test/model"
)
//Printer Printer
type Printer interface {
//方法的大小写的访问只与包有关
print()
}
//MyInt MyInt
type MyInt int
//print print
func (m MyInt) print() {
fmt.Println(m)
}
//MyString MyString
type MyString string
//print print
func (m MyString) print() {
fmt.Println(m)
}
//Show Show
func Show(p Printer) {
p.print()
}
func main() {
var a MyInt = 10
Show(a)
//有检测的类型断言
var p Printer = MyInt(12)
m, flg := p.(MyInt)
fmt.Printf("m type %T, flg type %T \n", m, flg)
if flg {
fmt.Println("p is MyInt")
}
//无检测的类型断言
mi := p.(MyInt)
fmt.Println("mi --->", mi)
//编译器会自动检测期望的类型是否实现了被断言实例的类型
//int does not implement Printer (missing print method)
//mt := p.(int)
//有检测类型断言 不能转换时不会报错
mss, mf := p.(MyString)
if mf {
fmt.Println(mss)
} else {
fmt.Println("mss is not MyString")
}
//无检测类型断言不能转换会直接抛异常
//panic: interface conversion: main.Printer is main.MyInt, not main.MyString
// ms := p.(MyString)
// fmt.Println("ms --->", ms)
TypeJudge(1, 2.1, float32(2.6), "jojo", mss, mi, model.Model{})
}
//TypeJudge TypeJudge
func TypeJudge(item ...interface{}) {
for idx, it := range item {
idx++
switch it.(type) {
case bool:
fmt.Printf("第%v个参数是 bool 类型,值是%v \n", idx, it)
case float32, float64:
fmt.Printf("第%v个参数是 浮点 类型,值是%v \n", idx, it)
case int8, int16, int32, int, int64:
fmt.Printf("第%v个参数是 整数 类型,值是%v \n", idx, it)
case string:
fmt.Printf("第%v个参数是 字符串 类型,值是%v \n", idx, it)
case MyInt:
fmt.Printf("第%v个参数是 main.MyInt 类型,值是%v \n", idx, it)
case model.Model:
fmt.Printf("第%v个参数是 model.Model 类型,值是%v \n", idx, it)
default:
fmt.Printf("第%v个参数值是%v 未能获取其类型\n", idx, it)
}
}
}