面向对象
- go没有class关键字,oop,但是我们可以把go当做面向对象的方式来编程
- go没有类,可以把struct作为类看待
-
继承
通过结构体的匿名嵌套,继承对应的字段和方法,举例 ```go package main
import “fmt”
type Person struct { Name string Email string Age int }
type Student struct { Person StudentId int }
// 附属于person类的方法 // 指针相当于单实例绑定 func (p *Person) SayHello() { fmt.Printf(“[Person.SayHello][name:%s]”, p.Name) }
func main() { p := Person{ Name: “xiaoyi”, Email: “qq.com”, Age: 18, } s := Student{ Person: p, StudentId: 123, } s.SayHello()
}
<a name="0HiIB"></a>## **多态 :通过接口做多态**<a name="IaKmT"></a>### **go接口**- interface{} 定义方法的集合- 多态体现在,各个结构体对象要实现 接口中定义的所有方法- 统一的函数调用入口 ,传入的接口- 各个结构体对象中 绑定的方法只能多不能少月 接口定义的- 方法的签名要一致:参数类型、参数个数,方法名称,函数返回值要一致- 多态的灵魂就是有个承载的容器,先把所有实现了接口的对象加进来,每个实例都要照顾的地方,直接遍历 调用方法即可```gopackage mainimport "fmt"// 体现多态// 告警通知的函数,根据不同的对象通知// 有个共同的通知方法,每种对象自己实现type notifer interface {// 动作,定义的方法notify()}// 普通用户type user struct {name stringemail string}// 管理员type admin struct {name stringage int}func (u *user) notify() {fmt.Printf("[普通用户][sendNotify to user %s]\n", u.name)}func (u *admin) notify() {fmt.Printf("[管理员][sendNotify to admin %s]\n", u.name)}// 多态的统一调用方法,入口func sendNotify(n notifer) {n.notify()}func main() {u1 := user{name: "小乙",email: "y@qq.com",}a1 := admin{name: "李逵",age: 18,}u1.notify()a1.notify()//var n notifer//n = &u1//n.notify()//ns:=make([]notifer,0)ns=append(ns,&u1)ns=append(ns,&a1)for _,n:=range ns{n.notify()}//}
常用举例 ,多个数据源推送数据和查询数据
package mainimport ("fmt""log")/*1. 多个数据源有2. query方法做查数据3. pushdata方法做写入数据*/// 方法集合type DataSource interface {PushData(data string)QueryData(name string) string}type redis struct {Name stringAddr string}func (r *redis) PushData(data string) {log.Printf("[PushData][ds.name:%s][data:%s]", r.Name, data)}func (r *redis) QueryData(name string) string {log.Printf("[QueryData][ds.name:%s][name:%s]", r.Name, name)return name + "redis"}type kafka struct {Name stringAddr string}func (k *kafka) PushData(data string) {log.Printf("[PushData][ds.name:%s][data:%s]", k.Name, data)}func (k *kafka) QueryData(name string) string {log.Printf("[QueryData][ds.name:%s][name:%s]", k.Name, name)return name + "kafka"}var Dm = make(map[string]DataSource)func main() {r:=redis{Name: "redis",Addr: "1.1",}k:=kafka{Name: "kafka",Addr: "2.2",}// 注册数据源到承载的容器中Dm["redis"] = &rDm["kafka"] = &k// 推送数据for i:=0;i<10;i++{key:=fmt.Sprintf("key_%d",i)for _,ds:=range Dm{ds.PushData(key)}}// 查询数据for i:=0;i<5;i++{key:=fmt.Sprintf("key_%d",i)for _,ds:=range Dm{res:=ds.QueryData(key)log.Println(res)}}}
空接口
类型断言 和类型判断
- 一个interface 需要类型转换的时候,语法 i.(T)
- v,ok:=i.(T) ```go package main
import “fmt”
func main() {
var s interface{} = "abc"s1, ok := s.(string)fmt.Println(s1, ok)s2, ok := s.(int)fmt.Println(s2, ok)switch s.(type) {case string:fmt.Println("是个string")case int:fmt.Println("是个int")default:fmt.Println("未知的type")}
} ```
