golang中使用结构体实现类
例子1(基于接口(interface),推荐):
package main
import "fmt"
type Shaper interface {
Name() string
Area() float32
}
// 长方形
type Rectangle struct {
a float32
b float32
}
func NewRectangle(a, b float32) *Rectangle {
return &Rectangle{
a: a, b: b,
}
}
// 值接收器,不建议使用
//func (r Rectangle) Name() string {
// return "Rectangle"
//}
// 指针接收器
func (r *Rectangle) Name() string {
return "rectangle"
}
func (r *Rectangle) Area() float32 {
return r.a * r.b
}
// 正方形
type Square struct {
a float32
}
func NewSquare(a float32) *Square {
return &Square{
a: a,
}
}
func (r *Square) Name() string {
return "square"
}
func (r *Square) Area() float32 {
return r.a * r.a
}
func main() {
r := NewRectangle(1.0, 2.0)
q := NewSquare(3.0)
shapes := []Shaper{r, q}
for _, v := range shapes {
fmt.Printf("name:%v, area:%v\n", v.Name(), v.Area())
}
println("done.")
}说明1:
- golang中的类基本上是实体类,类的抽象使用接口(interface)实现
- golang中,类实现可以实现多个接口,并且不需要像C++, JAVA等显式声明,只要实现了该接口的所有方法,就认为是实现了此接口
- golang中,类的成员函数可以使用值/指针接收器,二者的区别是调用时拷贝的对象不同,值接收器拷贝的是整个结构体,而指针接收器拷贝的是对象指针,后者效率更高,并且可以修改数据,建议不是特殊需要的话,都使用指针接收器。golang中没有this, super等,直接使用指定的接收器的名称。
- golang中的类没有构造函数/析构函数,通常使用NewXX(..)的公共方法构造类的实例。
- golang中,类的成员字段和成员函数的首字母大写,代表public属性,其他的代表包内可见属性(默认通常按private方式对待)
例子2(基于字段组合):
package main
import (
"time"
)
type Model struct {
Id uint
CreatedAt time.Time
UpdatedAt time.Time
}
func (m *Model) Description() string {
return "Model"
}
type A struct {
*Model // 这里使用*Model或者Model都可以,区别不大
Name string
}
// 可以覆盖父类方法
//func (m *A) Description() string {
// return "A"
//}
func main() {
now := time.Now()
a := &A{
Model: &Model{
Id: 1,
CreatedAt: now,
UpdatedAt: now,
},
Name: "test",
}
println(a.Id, a.Name)
println(a.Description())
println("done.")
}说明2:
- golang中使用字段或者字段指针组合的方式实现了一种类似继承的关系
- 父类中的字段和方法被子类继承,子类可以直接调用或者覆盖父类的实现
