duck typing
golang中实现某个接口不需要像其它语言使用 implemet 去继承实现,而是只要你的结构体包含接口所需的方法即可
package main
import "fmt"
type Person interface {
talk()
}
type XM struct {
}
func (receiver XM) talk() {
fmt.Println("I am XM")
}
func main() {
var p Person
p = XM{}
p.talk() // I am XM
}
nil不一定是空接口
初始化的接口是等于 nil的,接口底层其实有一个type来记录原始的struct,当某个struct赋值给接口时,接口会在type中记录该类型(就算是nil也会记录),此时接口打印出来是nil,但和nil并不相等
}
type XM struct {
}
func (X XM) talk() {
fmt.Println("I am XM")
}
func main() {
var p Person
if p == nil {
fmt.Println("var p Person is nil") //var p Person is nil
}
var a *XM
if a == nil {
fmt.Println("var a *XM is nil") //var a *XM is nil
}
p = a
if p != nil {
fmt.Println("var p != nil") //var p != nil
}
fmt.Println(p) // <nil>
}
组合代替继承
通过内嵌组合来继承功能,XM匿名内嵌了Person,就具有了Person的能力
package main
import "fmt"
type Person struct {
Name string
}
func (receiver Person) Talk() {
fmt.Printf("I am %s \n", receiver.Name)
}
type XM struct {
Person
}
func main() {
var xm XM
p := Person{Name: "Person"}
xm.Name = "XM"
xm.Talk() // I am XM
p.Talk() // I am Person
}
重写方法只需要声明一个同名方法即可
package main
import "fmt"
type Person struct {
Name string
}
func (receiver Person) Talk() {
fmt.Printf("I am %s \n", receiver.Name)
}
type XM struct {
Person
}
func (receiver XM) Talk() {
fmt.Printf("hello,I am %s", receiver.Name)
}
func main() {
var xm XM
xm.Name = "XM"
xm.Talk() // hello,I am XM
}
接口转换回具体的类型
struct 转为接口,只要struct 拥有 接口的方法,即可将struct 赋值给接口,如果想将接口转回struct,可以使用 result,ok := interface.(struct), ok 代表是否能够成功转换
package main
import "fmt"
type IAnimal interface {
Eat()
}
type Bridge struct {
}
func (b Bridge) Eat() {
fmt.Println("I can eat")
}
func (b Bridge) Fly() {
fmt.Println("I can fly")
}
type Fish struct {
}
func (f Fish) Eat() {
fmt.Println("I can eat")
}
func ShowTime(animal IAnimal) {
animal.Eat()
if b, ok := animal.(Bridge); ok {
b.Fly()
}
}
func main() {
var (
f Fish
b Bridge
)
ShowTime(f) // I can eat
fmt.Println("--------------")
ShowTime(b) // I can eat \n I can fly
}
ok 判断的是完全转换,就算不ok,转换后的结果也可以调用struct的方法,但是不建议这么做
文章来源:https://www.toymoban.com/news/detail-646352.html
package main
import "fmt"
type IAnimal interface {
Eat()
}
type Bridge struct {
Name string
}
func (b Bridge) Eat() {
fmt.Println(b.Name + "I can eat")
}
func (b Bridge) Fly() {
fmt.Println(b.Name + "I can fly")
}
type Fish struct {
Name string
}
func (f Fish) Eat() {
fmt.Println(f.Name + "I can eat")
}
func ShowTime(animal IAnimal) {
animal.Eat()
b, ok := animal.(Bridge)
fmt.Println(ok)
b.Fly()
}
func main() {
f := Fish{Name: "fish"}
b := Bridge{Name: "bridge"}
ShowTime(f)
// fishI can eat
// false
// I can fly
fmt.Println("--------------")
ShowTime(b)
//bridgeI can eat
// true
//bridgeI can fly
}
使用switch匹配接口的原始类型
struct.(type) 可以获取接口的原始类型,但是只能在switch中使用
文章来源地址https://www.toymoban.com/news/detail-646352.html
package main
import "fmt"
type IAnimal interface {
Eat()
}
type Bridge struct {
Name string
}
func (b Bridge) Eat() {
fmt.Println(b.Name + "I can eat")
}
func (b Bridge) Fly() {
fmt.Println(b.Name + "I can fly")
}
type Fish struct {
Name string
}
func (f Fish) Eat() {
fmt.Println(f.Name + "I can eat")
}
func ShowTime(animal IAnimal) {
switch animal.(type) {
case Fish:
fmt.Println("原先是Fish")
case Bridge:
fmt.Println("原先是Bridge")
}
}
func main() {
var (
f Fish
b Bridge
)
ShowTime(f) // 原先是Fish
ShowTime(b) // 原先是Bridge
}
到了这里,关于Golang 的面向对象的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!