赞
踩
基本介绍
封装的实现
封装案例如下:
package model import "fmt" type Student struct { name string age int gender string } // 访问name字段 func (stu Student) GetName() string { return stu.name } func (stu *Student) SetName(name string) { stu.name = name } // 访问age字段 func (stu Student) GetAge() int { return stu.age } func (stu *Student) SetAge(age int) { stu.age = age } // 访问gender字段 func (stu Student) GetGender() string { return stu.gender } func (stu *Student) SetGender(gender string) { stu.gender = gender } // Student的其他方法 func (stu Student) Print() { fmt.Printf("student info: <name: %s, age: %d, gender: %s>\n", stu.name, stu.age, stu.gender) }
使用上述包内结构体的案例如下:
package main
import (
"go_code/OOP2/Encapsulate/model"
)
func main() {
// var stu = model.Student{"Alice", 12, "女"} // 隐式赋值
var stu model.Student
stu.SetName("Alice")
stu.SetAge(12)
stu.SetGender("女")
stu.Print() // student info: <name: Alice, age: 12, gender: 女>
}
注意: Go中无法对结构体中不可导出的字段进行隐式赋值,可以通过给结构体绑定对应的setter和getter方法对不可导出的字段进行访问和赋值。
工厂函数
如果结构体类型的首字母小写(不可导出),那么其他包将无法直接使用该结构体类型来创建实例,这时可以在包内提供对应可导出的工厂函数来创建实例并返回。如下:
package model import "fmt" type student struct { name string age int gender string } // 工厂函数 func NewStudent(name string, age int, gender string) *student { return &student{ name: name, age: age, gender: gender, } } func (stu student) Print() { fmt.Printf("student info: <name: %s, age: %d, gender: %s>\n", stu.name, stu.age, stu.gender) }
其他包通过调用包中可导出的工厂函数,即可创建对应不可导出的结构体实例。如下:
package main
import (
"go_code/OOP2/Encapsulate/model"
)
func main() {
var stu = model.NewStudent("Alice", 12, "女")
stu.Print() // student info: <name: Alice, age: 12, gender: 女>
}
基本介绍
继承示意图如下:
继承的实现
继承案例如下:
package main import ( "fmt" ) // 基类 type Person struct { Name string Age int } func (per Person) PrintInfo() { fmt.Printf("name = %s, age = %d\n", per.Name, per.Age) } // 派生类 type Student struct { Person // 嵌套匿名结构体 StudentId int } func (stu Student) Study() { fmt.Printf("student %d is studying...\n", stu.StudentId) } // 派生类 type Teacher struct { *Person // 嵌套匿名结构体指针 TeacherId int } func (tch Teacher) Teach() { fmt.Printf("teacher %d is teaching...\n", tch.TeacherId) } func main() { var stu = Student{Person{"Alice", 12}, 100} stu.PrintInfo() // name = Alice, age = 12 stu.Study() // student 100 is studying... var tch = Teacher{&Person{"Bob", 22}, 200} tch.PrintInfo() // name = Bob, age = 22 tch.Teach() // teacher 200 is teaching... }
说明一下:
Type
的方式嵌套匿名结构体,也可以通过*Type
的方式嵌套匿名结构体指针。结构体变量名.int
的方式对其进行访问。组合
在结构体中嵌套有名结构体属于组合关系,在访问组合的结构体字段和方法时,必须带上结构体的字段名。如下:
package main import ( "fmt" ) // 车轮 type Wheel struct { Color string price int } // 自行车 type Bicycle struct { FrontWheel Wheel // 组合 RearWheel Wheel // 组合 // ... } func (bc Bicycle) Print() { fmt.Printf("前轮<color:%s, price:%d元> 后轮<color:%s, price:%d元>\n", bc.FrontWheel.Color, bc.FrontWheel.price, bc.RearWheel.Color, bc.RearWheel.price) } func main() { var bc = Bicycle{ FrontWheel: Wheel{"black", 100}, RearWheel: Wheel{"blue", 200}, } bc.Print() // 前轮<color:black, price:100元> 后轮<color:blue, price:200元> }
字段和方法访问细节
结构体字段和方法的访问流程:
案例如下:
package main import ( "fmt" ) // 基类 type Person struct { Name string Age int } func (per Person) PrintInfo() { fmt.Printf("name = %s, age = %d\n", per.Name, per.Age) } // 派生类 type Student struct { Person StudentId int } func (stu Student) Study() { fmt.Printf("student %d is studying...\n", stu.StudentId) } func (stu Student) PrintInfo() { fmt.Printf("name = %s, age = %d, id = %d\n", stu.Name, stu.Age, stu.StudentId) } func main() { var stu = Student{Person{"Alice", 12}, 100} fmt.Printf("name = %s\n", stu.Name) // name = Alice stu.PrintInfo() // name = Alice, age = 12, id = 100 }
代码说明:
Student变量.Name
访问的是嵌套的匿名结构体Person中的Name字段。Student变量.PrintInfo()
访问的是Student结构体的PrintInfo方法,而不是Person结构体的PrintInfo方法。多继承
多继承指的是一个结构体中嵌套了多个匿名结构体,如果嵌套的多个匿名结构体中有相同的字段名或方法名,那么在访问时需要通过匿名结构体的类型名进行指明访问。如下:
package main import ( "fmt" ) type Cat struct { Name string Age int } type Dog struct { Name string Age int } // 多继承 type Pet struct { Cat Dog } func main() { var pet = Pet{ Cat: Cat{ Name: "小猫", Age: 2, }, Dog: Dog{ Name: "小狗", Age: 3, }, } fmt.Printf("cat name = %s\n", pet.Cat.Name) // cat name = 小猫 fmt.Printf("dog name = %s\n", pet.Dog.Name) // dog name = 小狗 }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。