Go语言面向对象编程——结构化 方法 继承
Go语言面向对象编程——结构化 方法 继承
author: histonevon@zohomail.com
date: 2020/08/04
go语言支持类似于C语言中的面向对象的风格
1.结构体(类)定义
定义格式如下:
type 类型名 struct {
字段1 字段1类型
字段2 字段2类型
…
}
类型名:标识自定义结构体的名称,在同一个包内不能重复
字段1、字段2 ……:表示结构体字段名,结构体中的字段名必须唯一
字段1类型、字段2类型……:表示结构体各个字段的类型
//定义一个点类,坐标x y均为float64类型
type Point struct {
x float64
y float64
}
同类型变量可以写在同一行
以下语句同上面的语句等价
//定义一个点类,坐标x y均为float64类型
type Point struct {
x,y float64
}
可见性规则
成员或方法首字母大写 public
成员或方法首字母小写 private
// object project main.go
package main
import (
"fmt"
)
//对象
type Point struct {
x float64
y float64
}
func main() {
var p *Point = new(Point)
//通过内置函数new来建立对象,new返回一个指针,指向一块内存单元,其所占存储槽初始化为零。
p.x = 3 //p虽然是指针,但用取成员运算符即可,不需指向运算符
p.y = 4
q := new(Point) //这样也可
q.x = 5
q.y = 6
r := Point{7, 8} //直接初始化,value
var s Point = Point{9, 10} //完整直接初始化,value
var t *Point = &Point{11, 12} //完整直接初始化,pointer
u := &Point{13, 14} //简写,pointer
fmt.Println(p)
fmt.Println(q)
fmt.Println(r)
fmt.Println(s)
fmt.Println(t)
fmt.Println(u)
}
2.方法
声明了类,就可以将该类型显示的作为第一个参数来定义方法
eg.坐标变换器
// object project main.go
package main
import (
"fmt"
"math"
)
//对象
type Point struct {
x float64
y float64
}
func (self Point) Distance() float64 { //self为自身对象,实际上是函数的参数
return math.Sqrt(self.x*self.x + self.y*self.y)
}
func (self *Point) Scale(factor float64) { //坐标放大器
self.x *= factor
self.y *= factor
}
func main() {
p1 := Point{3, 4}
fmt.Println(p1.Distance())
p1.Scale(2) //坐标放大2
fmt.Println(p1)
}
在函数名前定义接收器,表示该方法作用的目标,也是方法的第一个参数
接收器类型和参数类型类似,可以是指针类型和非指针类型
方法名、参数列表、返回参数:格式与函数定义一致
官方建议使用接收器类型名的第一个小写字母,也可自己定义
//接收器变量为 Point型
func (self Point) Distance() float64 { //self为自身对象,实际上是函数的参数
return math.Sqrt(self.x*self.x + self.y*self.y)
}
//接收器变量为 Point型指针
func (self *Point) Scale(factor float64) { //坐标放大器
self.x *= factor
self.y *= factor
}
注意 在计算机中,小对象由于值复制时的速度较快,所以适合使用非指针接收器,大对象因为复制性能较低,适合使用指针接收器,在接收器和参数间传递时不进行复制,只是传递指针。
3.继承
// object project main.go
package main
import (
"fmt"
// "math"
)
//继承
//定义user类
type user struct {
name string
age byte
}
//定义方法
func (u user) Output() string {
return fmt.Sprintf("%+v", u) //Sprintf表示格式化输出为字符串
}
//定义leader类
type leader struct {
user //匿名成员,实现继承
title string
}
func main() {
var l leader
l.name = "Tim" //继承user.name
l.age = 19 //继承user.age
l.title = "sales manager"
fmt.Println(l.Output()) //继承user.Output()
//匿名成员有和类型一样的名字,所以可以这样
l.user.name = "Tom" //未继承user.name
l.user.age = 20 //未继承user.age
fmt.Println(l.user.Output()) //未继承user.Output()
}
go通过匿名组合来实现类似继承的功能,在子类中匿名声明父类即可
子类继承后可以通过 "." 直接访问父类成员,如:
l.name = "Tim"
也可以不进行继承,通过访问匿名成员来访问父类成员,如:
l.user.name = "Tom"
Sprintf表示格式化输出为字符串
4.总结
面向对象只是换了一种语法方式表达而已