Golang——面向对象
面向对象:结构体实现
继承:匿名字段
type Tea struct {
name string
age int
}
type Stu struct {
Tea // 匿名字段,为Tea类型,继承了Tea
score int
name string
}
func main() {
s := Stu{Tea{"aaa", 111}, 111} // Stu对象,位置赋值
l := Stu{score: 111} // 指定score,关键字赋值
fmt.Println(s, l) // {{aaa 111} 111} {{ 0} 111}
s.Tea.name = "哈哈哈"
fmt.Println(s) // {{哈哈哈 111} 111}
s.age = 11111 // 修改父类Tea的age属性,子类Stu里没有这个属性
fmt.Println(s) // {{哈哈哈 11111} 111} Stu无age属性,修改的是父类Tea的age属性
}
优先使用子类的元素,没有就使用父类的元素。
s.name // 子类中的name属性
s.Tea.name // 父类中的name属性
指针类型匿名字段
type Tea struct {
name string
age int
}
type Stu struct {
Tea // 匿名字段,为Tea类型,继承了Tea
score int
}
type Stu2 struct {
*Tea // 指针类型元素
score int
}
// 值类型匿名变量是连续的地址,指针类型匿名变量是指向地址
func main() {
t := Stu2{score: 111}
fmt.Println(t) // {<nil> 111}
t.Tea = new(Tea)
t.Tea.name = "aaa"
fmt.Println(t, t.name, t.age) // {0xc000098440 111} aaa 0
(*t.Tea).name = "gogogo"
fmt.Println(t) // {0xc0000044c0 111}
t.Tea = &Tea{"aaa", 1} // {0xc000098460 111}
fmt.Println(t, t.name) // {0xc0000044e0 111} aaa
}
类方法
type Tea struct {
name string
age int
}
type Stu struct {
Tea // 匿名字段,为Tea类型,继承了Tea
score int
}
func (s Stu) jiao() { // 对象方法
fmt.Println("aaa")
}
func jiao() { // 普通方法
fmt.Println("aaa")
}
func (t Tea) tj() { // 对象方法
fmt.Println("bbb")
}
// 值类型匿名变量是连续的地址,指针类型匿名变量是指向地址
func main() {
s := Stu{Tea{"aaa", 11}, 100}
fmt.Println(s)
s.jiao()
s.tj()
jiao()
}
// 对象方法 和 普通方法 可以重名
// 属性可以继承,方法同样可以
类方法:值传递与指针传递
type Tea struct {
name string
age int
}
type Stu struct {
Tea // 匿名字段,为Tea类型,继承了Tea
score int
}
func (s Stu) jiao() { // 值传递
s.score = 11111
fmt.Println(s.score)
}
func (s *Stu) jiao2() { // 指针传递
s.score = 22222
fmt.Println(s.score)
}
func jiao() {
fmt.Println("aaa")
}
func (t Tea) tj() {
fmt.Println("bbb")
}
// 值类型匿名变量是连续的地址,指针类型匿名变量是指向地址
func main() {
s := Stu{Tea{"aaa", 11}, 100}
fmt.Println(s)
fmt.Println(s.score) // 100
s.jiao() // 11111
fmt.Println(s.score) //100
s.jiao2() // 22222
fmt.Println(s.score) // 22222
}
// 值传递是对象的副本,不影响原来的对象
// 指针传递是原对象本身,影响了对象本身
方法重写
子类重写了父类的方法
s.jiao // 子类的方法
s.Tea.jiao // 父类的方法
方法值与方法表达式
type Tea struct {
name string
age int
}
type Stu struct {
Tea // 匿名字段,为Tea类型,继承了Tea
score int
}
func (s Stu) jiao() { // 值传递
s.score = 11111
fmt.Println(s.score)
}
func (s *Stu) jiao2() { // 指针传递
s.score = 22222
fmt.Println(s.score)
}
// 值类型匿名变量是连续的地址,指针类型匿名变量是指向地址
func main() {
s := Stu{Tea{"aaa", 11}, 100}
p := s.jiao // 方法值:具体对象的方法
p() // s.jiao()
p1 := Stu.jiao // 方法表达式:类的方法,没有绑定对象
// p1() // 不行,需要传对象
// not enough arguments in call to p1
// have ()
// want (Stu)
p1(s) // 可以
// p2 := Stu.jiao2 // 不行,jiao2 是指针传递的方法
// invalid method expression Stu.jiao2 (needs pointer receiver: (*Stu).jiao2)
p2 := (*Stu).jiao2
// p2(s) // 不行,必须传指针对象
p2(&s)
p3 := (*Stu).jiao // jiao是值传递方法,也可以这样,传参也要地址
p3(&s)
}