1 定义结构体

Go语言的结构体(struct)和其他语言的类(class)有同等的地位,但Go语言放弃了包括继承在内的大量面向对象特性,只保留了组合(composition)这个最基础的特性

  1. type Rect struct {
  2. x, y float64
  3. width, height float64
  4. }

2 定义方法

Golang 方法总是绑定对象实例,并隐式将实例作为第一实参 (receiver)。

  • 参数 receiver 可任意命名。如方法中未曾使用 ,可省略参数名。
  • 参数 receiver 类型可以是 T 或 *T。基类型 T 不能是接口或指针。
    1. func (r *Rect) Area() float64 {
    2. return r.width * r.height
    3. }

    (1) 匿名字段

    ```go package main

import “fmt”

type User struct { id int name string }

type Manager struct { User // 匿名字段 }

func (self *User) ToString() string { // receiver = &(Manager.User) return fmt.Sprintf(“User: %p, %v”, self, self) }

func main() { m := Manager{User{1, “Tom”}} fmt.Printf(“Manager: %p\n”, &m) fmt.Println(m.ToString()) // 编绎器自动查找 }

  1. <a name="isRHB"></a>
  2. ## (2) 方法集
  3. Golang方法集 :每个类型都有与之关联的方法集
  4. - 类型 T 方法集包含全部 receiver T 方法。
  5. - 类型 *T 方法集包含全部 receiver T + *T 方法。
  6. - 如类型 S 包含匿名字段 T,则 S 和 *S 方法集包含 T 方法。
  7. - 如类型 S 包含匿名字段 *T,则 S 和 *S 方法集包含 T + *T 方法。
  8. - 不管嵌入 T 或 *T,*S 方法集总是包含 T + *T 方法。
  9. <a name="vLX8y"></a>
  10. ## (3) 表达式
  11. - instance.method(args...)称为 method value,
  12. - <type>.func(instance, args...)称为 method expression。
  13. - 两种调用方法的方式等价
  14. ```go
  15. instance.method(args...) ---> <type>.func(instance, args...)

3 初始化

可以通过如下几种方法

  1. rect1 := new(Rect)
  2. rect2 := &Rect{}
  3. rect3 := &Rect{0,0,100,200}
  4. rect4 := &Rect{width: 100, height: 200}

在Go语言中,未进行显式初始化的变量都会被初始化为该类型的零值,
例如 bool 类型的零值为 false, int 类型的零值为0, string 类型的零值为””。

在Go语言中没有构造函数的概念,对象的创建通常交由一个全局的创建函数来完成,以NewXXX 来命名,表示“构造函数”

  1. func NewRect(x, y, width, height float64) *Rect {
  2. return &Rect{x, y, width, height}
  3. }

4 匿名组合(继承)

  1. type Base struct {
  2. Name string
  3. }
  4. func (base *Base) Foo() { ... }
  5. func (base *Base) Bar() { ... }
  6. type Derive struct {
  7. Base
  8. ...
  9. }
  10. func (d *Derive) Bar() {
  11. d.Base.Bar() // 调用 d.Foo() 和调用 d.Base.Foo() 效果一致
  12. }

在“派生类” Derive没有改写“基类” Base 的成员方法时,相应的方法就被“继承”,