面向对象

  • go没有class关键字,oop,但是我们可以把go当做面向对象的方式来编程
  • go没有类,可以把struct作为类看待
  • 类的方法是啥: 给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()

}

  1. <a name="0HiIB"></a>
  2. ## **多态 :通过接口做多态**
  3. <a name="IaKmT"></a>
  4. ### **go接口**
  5. - interface{} 定义方法的集合
  6. - 多态体现在,各个结构体对象要实现 接口中定义的所有方法
  7. - 统一的函数调用入口 ,传入的接口
  8. - 各个结构体对象中 绑定的方法只能多不能少月 接口定义的
  9. - 方法的签名要一致:参数类型、参数个数,方法名称,函数返回值要一致
  10. - 多态的灵魂就是有个承载的容器,先把所有实现了接口的对象加进来,每个实例都要照顾的地方,直接遍历 调用方法即可
  11. ```go
  12. package main
  13. import "fmt"
  14. // 体现多态
  15. // 告警通知的函数,根据不同的对象通知
  16. // 有个共同的通知方法,每种对象自己实现
  17. type notifer interface {
  18. // 动作,定义的方法
  19. notify()
  20. }
  21. // 普通用户
  22. type user struct {
  23. name string
  24. email string
  25. }
  26. // 管理员
  27. type admin struct {
  28. name string
  29. age int
  30. }
  31. func (u *user) notify() {
  32. fmt.Printf("[普通用户][sendNotify to user %s]\n", u.name)
  33. }
  34. func (u *admin) notify() {
  35. fmt.Printf("[管理员][sendNotify to admin %s]\n", u.name)
  36. }
  37. // 多态的统一调用方法,入口
  38. func sendNotify(n notifer) {
  39. n.notify()
  40. }
  41. func main() {
  42. u1 := user{
  43. name: "小乙",
  44. email: "y@qq.com",
  45. }
  46. a1 := admin{
  47. name: "李逵",
  48. age: 18,
  49. }
  50. u1.notify()
  51. a1.notify()
  52. //var n notifer
  53. //n = &u1
  54. //n.notify()
  55. //
  56. ns:=make([]notifer,0)
  57. ns=append(ns,&u1)
  58. ns=append(ns,&a1)
  59. for _,n:=range ns{
  60. n.notify()
  61. }
  62. //
  63. }

常用举例 ,多个数据源推送数据和查询数据

  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. )
  6. /*
  7. 1. 多个数据源有
  8. 2. query方法做查数据
  9. 3. pushdata方法做写入数据
  10. */
  11. // 方法集合
  12. type DataSource interface {
  13. PushData(data string)
  14. QueryData(name string) string
  15. }
  16. type redis struct {
  17. Name string
  18. Addr string
  19. }
  20. func (r *redis) PushData(data string) {
  21. log.Printf("[PushData][ds.name:%s][data:%s]", r.Name, data)
  22. }
  23. func (r *redis) QueryData(name string) string {
  24. log.Printf("[QueryData][ds.name:%s][name:%s]", r.Name, name)
  25. return name + "redis"
  26. }
  27. type kafka struct {
  28. Name string
  29. Addr string
  30. }
  31. func (k *kafka) PushData(data string) {
  32. log.Printf("[PushData][ds.name:%s][data:%s]", k.Name, data)
  33. }
  34. func (k *kafka) QueryData(name string) string {
  35. log.Printf("[QueryData][ds.name:%s][name:%s]", k.Name, name)
  36. return name + "kafka"
  37. }
  38. var Dm = make(map[string]DataSource)
  39. func main() {
  40. r:=redis{
  41. Name: "redis",
  42. Addr: "1.1",
  43. }
  44. k:=kafka{
  45. Name: "kafka",
  46. Addr: "2.2",
  47. }
  48. // 注册数据源到承载的容器中
  49. Dm["redis"] = &r
  50. Dm["kafka"] = &k
  51. // 推送数据
  52. for i:=0;i<10;i++{
  53. key:=fmt.Sprintf("key_%d",i)
  54. for _,ds:=range Dm{
  55. ds.PushData(key)
  56. }
  57. }
  58. // 查询数据
  59. for i:=0;i<5;i++{
  60. key:=fmt.Sprintf("key_%d",i)
  61. for _,ds:=range Dm{
  62. res:=ds.QueryData(key)
  63. log.Println(res)
  64. }
  65. }
  66. }

空接口


类型断言 和类型判断

  • 一个interface 需要类型转换的时候,语法 i.(T)
  • v,ok:=i.(T) ```go package main

import “fmt”

func main() {

  1. var s interface{} = "abc"
  2. s1, ok := s.(string)
  3. fmt.Println(s1, ok)
  4. s2, ok := s.(int)
  5. fmt.Println(s2, ok)
  6. switch s.(type) {
  7. case string:
  8. fmt.Println("是个string")
  9. case int:
  10. fmt.Println("是个int")
  11. default:
  12. fmt.Println("未知的type")
  13. }

} ```