文章目录
- 1、封装
- 2、继承
- 3、继承的注意点
1、封装
- 隐藏实现细节
- 保证数据安全(控制变量或方法的访问范围,private)
Go中实现封装:
- 结构体、字段的首字母小写(Java的private)
- 提供一个工厂模式函数,首字母大写(public)
//提供一个首字母大写的Set方法(类似其它语言的public),用于对属性判断并赋值
func (var 结构体类型名)SetXxx(参数列表){
//加入数据验证的业务逻辑
var.Age =参数
}
//提供一个首字母大写的Get方法(类似其它语言的public),用于获取属性的值
func (var 结构体类型名) GetXxx() (返回值列表){
return var.字段;
}
示例:
其他包中创建示例,并对字段赋值:
2、继承
和Java的extends相比,Go中对结构体的继承,通过匿名结构体实现:如果一个struct嵌套了另一个匿名结构体,那么这个结构体可以直接访问匿名结构体的字段和方法,从而实现了继承特性。
代码实现:
package main
import (
"fmt"
)
//定义动物结构体:
type Animal struct{
Age int
Weight float32
}
//给Animal绑定方法:喊叫:
func (an *Animal) Shout(){
fmt.Println("我可以大声喊叫")
}
给Animal绑定方法:自我展示:
func (an *Animal) ShowInfo(){
fmt.Printf("动物的年龄是:%v,动物的体重是:%v",an.Age,an.Weight)
}
//定义结构体:Cat
type Cat struct{
//为了复用性,体现继承思维,嵌入匿名结构体:——》将Animal中的字段和方法都达到复用
Animal
}
//对Cat绑定特有的方法:
func (c *Cat) scratch(){
fmt.Println("我是小猫,我可以挠人")
}
func main(){
//创建Cat结构体示例:
cat := &Cat{}
cat.Animal.Age = 3
cat.Animal.Weight = 10.6
cat.Animal.Shout()
cat.Animal.ShowInfo()
cat.scratch()
}
3、继承的注意点
1)结构体可以使用嵌套匿名结构体所有的字段和方法,无关父结构体字段方法的大小写
package main
import (
"fmt"
)
//定义动物结构体:
type Animal struct{
Age int
weight float32
}
//给Animal绑定方法:喊叫:
func (an *Animal) Shout(){
fmt.Println("我可以大声喊叫")
}
给Animal绑定方法:自我展示:
func (an *Animal) showInfo(){
fmt.Printf("动物的年龄是:%v,动物的体重是:%v",an.Age,an.weight)
}
//定义结构体:Cat
type Cat struct{
Animal
}
func (c *Cat) scratch(){
fmt.Println("我是小猫,我可以挠人")
}
func main(){
//创建Cat结构体示例:
cat := &Cat{}
cat.Animal.Age = 3
cat.Animal.weight = 10.6
cat.Animal.Shout()
cat.Animal.showInfo() //小写也可以访问!!!1
cat.scratch()
}
2)匿名结构体字段访问可以简化。下面两种等价:cat.Age --->cat对应的结构体中找是否有Age字段,如果有直接使用,如果没有就去找嵌入的结构体类型中的Age
3)当结构体和匿名结构体有相同的字段或者方法时,编译器采用就近访问原则访问。想访问匿名结构体的方法或字段,可加上结构体名
cat := &Cat{}
cat.weight = 9.4
cat.Age = 10 //就近原则
cat.Animal.Age = 20 //打破就近
cat.showInfo()//就近原则
cat.Animal.showInfo() //打破就近
4)和Java不同,Go支持多继承
package main
import (
"fmt"
)
type A struct{
a int
b string
}
type B struct{
c int
d string
}
type C struct{
A
B
}
func main(){
//构建C结构体实例:
c := C{A{10,"aaa"},B{20,"ccc"}}
fmt.Println(c)
}
5)多继承时,父结构体若出现相同的字段名或者方法名,访问时带结构体类型名
package main
import (
"fmt"
)
type A struct{
a int
b string
}
type B struct{
c int
d string
a int
}
type C struct{
A
B
}
func main(){
//构建C结构体实例:
c := C{A{10,"aaa"},B{20,"ccc",50}}
fmt.Println(c.b)
fmt.Println(c.d)
fmt.Println(c.A.a) 访问同名的字段
fmt.Println(c.B.a) 访问同名的字段
}
6)结构体的匿名字段可以是基本数据类型
7)嵌套匿名结构体后,也可以在创建结构体变量(实例)时,直接指定各个匿名结构体字段的值
8)嵌入匿名结构体的指针也是可以的
9)构体的字段可以是结构体类型的,注意这是组合模式,无关继承
type B struct{
c int
d string
a int
}