1 定义结构体
Go语言的结构体(struct)和其他语言的类(class)有同等的地位,但Go语言放弃了包括继承在内的大量面向对象特性,只保留了组合(composition)这个最基础的特性
type Rect struct {
x, y float64
width, height float64
}
2 定义方法
Golang 方法总是绑定对象实例,并隐式将实例作为第一实参 (receiver)。
- 参数 receiver 可任意命名。如方法中未曾使用 ,可省略参数名。
- 参数 receiver 类型可以是 T 或 *T。基类型 T 不能是接口或指针。
func (r *Rect) Area() float64 {
return r.width * r.height
}
(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()) // 编绎器自动查找 }
<a name="isRHB"></a>
## (2) 方法集
Golang方法集 :每个类型都有与之关联的方法集
- 类型 T 方法集包含全部 receiver T 方法。
- 类型 *T 方法集包含全部 receiver T + *T 方法。
- 如类型 S 包含匿名字段 T,则 S 和 *S 方法集包含 T 方法。
- 如类型 S 包含匿名字段 *T,则 S 和 *S 方法集包含 T + *T 方法。
- 不管嵌入 T 或 *T,*S 方法集总是包含 T + *T 方法。
<a name="vLX8y"></a>
## (3) 表达式
- instance.method(args...)称为 method value,
- <type>.func(instance, args...)称为 method expression。
- 两种调用方法的方式等价
```go
instance.method(args...) ---> <type>.func(instance, args...)
3 初始化
可以通过如下几种方法
rect1 := new(Rect)
rect2 := &Rect{}
rect3 := &Rect{0,0,100,200}
rect4 := &Rect{width: 100, height: 200}
在Go语言中,未进行显式初始化的变量都会被初始化为该类型的零值,
例如 bool 类型的零值为 false, int 类型的零值为0, string 类型的零值为””。
在Go语言中没有构造函数的概念,对象的创建通常交由一个全局的创建函数来完成,以NewXXX 来命名,表示“构造函数”
func NewRect(x, y, width, height float64) *Rect {
return &Rect{x, y, width, height}
}
4 匿名组合(继承)
type Base struct {
Name string
}
func (base *Base) Foo() { ... }
func (base *Base) Bar() { ... }
type Derive struct {
Base
...
}
func (d *Derive) Bar() {
d.Base.Bar() // 调用 d.Foo() 和调用 d.Base.Foo() 效果一致
}
在“派生类” Derive没有改写“基类” Base 的成员方法时,相应的方法就被“继承”,