Go语言深入学习面向对象

目录匿名字段接口匿名字段go支持只提供类型而不写字段名的方式,也就是匿名字段,也称为嵌入字段packagemainimport"fmt"//人typePersonstruct{namestringsexstringagein

目录


匿名字段

go支持只提供类型而不写字段名的方式,也就是匿名字段,也称为嵌入字段

package main

import "fmt"

//人
type Person struct {
    name string
    sex  string
    age  int
}

// 自定义类型
type mystr string

type Student struct {
    Person
    id   int
    addr string
    //同名字段
    name string
}

// 学生
type Student2 struct {
    Person
    int
    mystr
}

func main() {
  // 初始化
  s1 := Student{Person{"5lmh", "man", 20}, 1, "bj"}
  fmt.Println(s1)

  s2 := Student{Person: Person{"5lmh", "man", 20}}
  fmt.Println(s2)

  var s Student
  // 给自己字段赋值了
  s.name = "5lmh"
  fmt.Println(s)

  // 若给父类同名字段赋值,如下
  s.Person.name = "枯藤"
    fmt.Print

指针类型匿名字段

package main
import "fmt"

//人
type Person struct {
  name string
  sex  string
  age  int
}

// 学生
type Student struct {
  *Person
  id   int
  addr string
}

func main() {
  s1 := Student{&Person{"5lmh", "man", 18}, 1, "bj"}
  fmt.Println(s1)
  fmt.Println(s1.name)
  fmt.Println(s1.Person.name)
}

接口

接口类型

在Go语言中接口(interface)是一种类型,一种抽象的类型。

interface是一组method的集合,是duck-type programming的一种体现。接口做的事情就像是定义一个协议(规则),只要一台机器有洗衣服和甩干的功能,我就称它为洗衣机。不关心属性(数据),只关心行为(方法)。

为了保护你的Go语言职业生涯,请牢记接口(interface)是一种类型。

type Cat struct{}
func (c Cat) Say() string { return "喵喵喵" }
type Dog struct{}
func (d Dog) Say() string { return "汪汪汪" }
func main() {
  c := Cat{}
  fmt.Println("猫:", c.Say())
  d := Dog{}
  fmt.Println("狗:", d.Say())
}

接口的定义

Go语言提倡面向接口编程。

  • 接口是一个或多个方法签名的集合。

  • 任何类型的方法集中只要拥有该接口'对应的全部方法'签名。

  • 就表示它 "实现" 了该接口,无须在该类型上显式声明实现了哪个接口。

  • 这称为Structural Typing。

  • 所谓对应方法,是指有相同名称、参数列表 (不包括参数名) 以及返回值。

  • 当然,该类型还可以有其他方法。

  • 接口只有方法声明,没有实现,没有数据字段。

  • 接口可以匿名嵌入其他接口,或嵌入到结构中。

  • 对象赋值给接口时,会发生拷贝,而接口内部存储的是指向这个复制品的指针,既无法修改复制品的状态,也无法获取指针。

  • 只有当接口存储的类型和对象都为nil时,接口才等于nil。

  • 接口调用不会做receiver的自动转换。

  • 接口同样支持匿名字段方法。

  • 接口也可实现类似OOP中的多态。

  • 空接口可以作为任何类型数据的容器。

  • 一个类型可实现多个接口。

  • 接口命名习惯以 er 结尾。

每个接口由数个方法组成,接口的定义格式如下:

  type 接口类型名 interface{
      方法名1( 参数列表1 ) 返回值列表1
      方法名2( 参数列表2 ) 返回值列表2
      …
  } 

其中:

  1. 接口名:使用type将接口定义为自定义的类型名。Go语言的接口在命名时,一般会在单词后面添加er,如有写操作的接口叫Writer,有字符串功能的接口叫Stringer等。接口名最好要能突出该接口的类型含义。
  2. 方法名:当方法名首字母是大写且这个接口类型名首字母也是大写时,这个方法可以被接口所在的包(package)之外的代码访问。
  3. 参数列表、返回值列表:参数列表和返回值列表中的参数变量名可以省略。
    
    // Sayer 接口
    type Sayer interface {
    say()
    } 
    type dog struct {}
    type cat struct {} 
    // dog实现了Sayer接口
    func (d dog) say() {
    fmt.Println("汪汪汪")
    }

// cat实现了Sayer接口 func (c cat) say() { fmt.Println("喵喵喵") } func main() { var x Sayer // 声明一个Sayer类型的变量x a := cat{} // 实例化一个cat b := dog{} // 实例化一个dog x = a // 可以把cat实例直接赋值给x x.say() // 喵喵喵 x = b // 可以把dog实例直接赋值给x x.say() // 汪汪汪 }

// 值接收者和指针接收者 type Mover interface { move() } type dog struct {} // 值接收者实现接口 func (d dog) move() { fmt.Println("狗会动") } func main() { var x Mover var wangcai = dog{} // 旺财是dog类型 x = wangcai // x可以接收dog类型 var fugui = &dog{} // 富贵是dog类型 x = fugui // x可以接收dog类型 x.move() } // 指针接收者实现接口 func (d dog) move() { fmt.Println("狗会动") } func main() { var x Mover var wangcai = dog{} // 旺财是dog类型 x = wangcai // x不可以接收dog类型 var fugui = &dog{} // 富贵是dog类型 x = fugui // x可以接收*dog类型 }


### 一个类型实现多个接口
```go
// Sayer 接口
type Sayer interface {
    say()
}
// Mover 接口
type Mover interface {
    move()
} 
// 实现Sayer接口
func (d dog) say() {
  fmt.Printf("%s会叫汪汪汪\n", d.name)
}

// 实现Mover接口
func (d dog) move() {
  fmt.Printf("%s会动\n", d.name)
}

func main() {
  var x Sayer
  var y Mover

  var a = dog{name: "旺财"}
  x = a
  y = a
  x.say()
  y.move()
} 

多个类型实现同一接口

// Mover 接口
type Mover interface {
    move()
} 
type dog struct {
    name string
}

type car struct {
    brand string
}

// dog类型实现Mover接口
func (d dog) move() {
    fmt.Printf("%s会跑\n", d.name)
}

// car类型实现Mover接口
func (c car) move() {
    fmt.Printf("%s速度70迈\n", c.brand)
}
func main() {
    var x Mover
    var a = dog{name: "旺财"}
    var b = car{brand: "保时捷"}
    x = a
    x.move()
    x = b
    x.move()
} 

接口嵌套

// Sayer 接口
type Sayer interface {
    say()
}

// Mover 接口
type Mover interface {
    move()
}

// 接口嵌套
type animal interface {
    Sayer
    Mover
} 
ype cat struct {
    name string
}

func (c cat) say() {
    fmt.Println("喵喵喵")
}

func (c cat) move() {
    fmt.Println("猫会动")
}

func main() {
    var x animal
    x = cat{name: "花花"}
    x.move()
    x.say()
}  

空接口

func main() {
    // 定义一个空接口x
    var x interface{}
    s := "pprof.cn"
    x = s
    fmt.Printf("type:%T value:%v\n", x, x)
    i := 100
    x = i
    fmt.Printf("type:%T value:%v\n", x, x)
    b := true
    x = b
    fmt.Printf("type:%T value:%v\n", x, x)
}
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
天涯学馆
天涯学馆
0x9d6d...50d5
资深大厂程序员,12年开发经验,致力于探索前沿技术!