1、面向对象三大特性
1.1、封装
封装:把抽象出的字段和对字段的操作封装在一起,数据被保护在内部,程序的其它包只有通过被授权的操作(方法),才能对字段进行修改,其作用有:
Go 对面向对象做了极大简化,并不强调封装特性,下列示例进行模拟实现:
在 person 包下新建 person.go 文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
   | type person struct {     Name string     age int             }
 
  func NewPerson(name string) *person {     return &person{         Name: name,     } }
  func (p *person) SetAge(age int) {     if age > 0 && age < 150 {                 p.age = age     } else {         fmt.Println("年龄不合法")     } }
  func (p *person) GetAge() int {     return p.age }
 
  | 
 
main.go文件操作person:
1 2 3 4 5 6 7 8 9 10 11 12
   | package main
  import (     "demo/person"                         "fmt" )
  func main() {     p := person.NewPerson("Tom")     p.SetAge(18)     fmt.Println(p) }
 
  | 
 
1.2、继承
在 Go 中,如果一个 struct 嵌套了另一个匿名结构体,那么这个结构体可以直接访 问匿名结构体的字段和方法,从而实现了继承特性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
   | type Father struct {     Name string     age int }
  func (f *Father) run() {     fmt.Println(f.Name + " like running...") }
  type Son struct {     Father               }
  func main() {
      var s Son
                
           s.Name = "Tom"     s.age = 10     s.run() }
 
  | 
 
注意:
- 当结构体和匿名结构体有相同的字段或者方法时,编译器采用就近访问原则访问,如果希望访问匿名结构体的字段和方法,可以通过匿名结构体名来区分。
 
- 结构体嵌入多个匿名结构体,如果两个匿名结构体有相同的字段和方法(同时结构体本身没有同名的字段和方法),访问时必须明确指定匿名结构体名字,否则编译报错。
 
- 如果一个 struct 嵌套了一个有名结构体,这种模式就是组合,如果是组合关系,那么在访问组合的结构体的字段或方法时,必须带上结构体的名字。
 
关于多重继承:如果一个 struct 嵌套了多个匿名结构体,那么该结构体可以直接访问嵌套的匿名结构体的字段和方法,从而实现多重继承。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
   | type Father1 struct {     Name string     age int }
  func (f *Father1) run() {     fmt.Println(f.Name + " like running...") }
  type Father2 struct {     Like string }
 
  type Son1 struct {     Father1     Father2 }
  type Son2 struct {     *Father1     *Father2 }
  func main() {
      s1 := &Son1 {         Father1{             Name: "Tom",             age: 10,         },         Father2{             Like: "伏特加",         },     }
      fmt.Println(s1)
      s2 := &Son2{         &Father1{             Name: "Tom",             age: 10,         },         &Father2{              Like: "伏特加",         },     }     fmt.Println(s2.Father1)
  }
 
  | 
 
输出结果:
1 2
   | &{{Tom 10} {伏特加}} &{Tom 10}
 
  | 
 
1.3、多态
多态与接口(interface)有关联,参见接口章节