golang面向对象
一、方法
1、方法是作用在指定的数据类型上,和指定的数据类型绑定,因此自定义类型都可以有方法,而不仅仅是struct;
2、方法的申明和格式调用:
package main
import (
"fmt"
)
type Person struct{
Name string
}
func (p Person) test(){
fmt.Println(p.Name)
}
func main(){
p := Person{Name: "Tom"}
p.test()
}
注意:结构体对象传入方法中是值传递,和函数传递参数一样。如果在方法中改变结构体变量的值,可以通过结构体指针的方式来处理。
package main
import (
"fmt"
)
type Person struct{
Name string
}
func (p *Person) test(){
fmt.Println((*p).Name)
}
func main(){
p := &Person{Name: "Tom"}
p.test()
}
二、封装:
1、什么是封装?
封装就是把抽象出的字段和对字段的操作封装在一起,数据被保护在内部,程序的其它包只有通过被授权的操作方法才能对字段就行操作。
2、封装的好处:
1)隐藏实现细节;
2)可以对数据进行验证,保证数据安全合理。
3、golang中如何实现封装?
package main
import (
"fmt"
)
type person struct{
Name string
age int
}
func NewPerson(name string) *person {
p := person{
Name: name,
}
return &p
}
func (p *person) SetAge(age int){
if age > 0 && age < 150{
(*p).age = age
} else {
fmt.Println("对不起,你输入的年龄范围不正确。")
}
}
func (p *person) GetAge() int {
return (*p).age
}
func main(){
p := NewPerson("Tom")
p.SetAge(22)
fmt.Println(p.Name)
fmt.Println(p.GetAge)
fmt.Println(*p)
}
// Tom
// 0xbc5a60
// {Tom 22}
三、继承
当多个结构体存在相同的属性和方法时可以从这些结构体中抽象出结构体,在该结构体中定义这些相同的属性和方法,其它的结构体中不需要重新定义这些属性和方法,只需要嵌入一个匿名结构体即可。
也就是说,在golang中如果一个struct嵌套了另一个匿名结构体,那个这个struct可以直接访问这个匿名结构的属性和方法,从而实现了继承特性。
继承的优点:
1、提高代码的复用性和扩展性;
package main
import (
"fmt"
)
type Animal struct{
Age int
Weight float32
}
func (an *Animal) Shout(){
fmt.Println("我可以大声喊叫")
}
func (an *Animal) ShowInfo(){
fmt.Println("动物的年龄是:%v,动物的体重是:%v", an.Age, an.Weight)
}
type Cat struct{
Animal
}
func (c *Cat) scratch(){
fmt.Println("我是小猫,我可以挠人。")
}
func main(){
cat := &Cat{}
cat.Animal.Age = 3
cat.Animal.Weight = 10.6
cat.Animal.Shout()
cat.Animal.ShowInfo()
cat.scratch()
}
注意事项:
1、结构体可以使用嵌套匿名结构体所有的字段和方法,即:首字母大写和小写的字段、方法都可以使用;
2、匿名结构体字段访问可以简化;
3、当结构体和匿名结构体有相同的字段和方法时,编译器采用就近访问原则进行访问,如果希望访问匿名结构体属性和方法,可以通过匿名结构体名来区分;
4、golang中支持多继承;
package main
import (
"fmt"
)
type A struct{
a1 string
a2 int
}
type B struct{
b1 string
b2 int
}
type C struct{
A
B
}
func main(){
c := C{A{"a1", 10}, B{"b1", 20}}
fmt.Println(c)
}
5、如果嵌入的匿名结构体有相同的属性名或方法,则在访问时需要通过匿名结构体类型名来区分;
6、结构体的匿名字段可以是基本数据类型;
package main
import (
"fmt"
)
type A struct{
a1 string
a2 int
}
type B struct{
b1 string
b2 int
}
type C struct{
A
B
int
}
func main(){
c := C{A{"a1", 10}, B{"b1", 20}, 888}
fmt.Println(c.a1)
fmt.Println(c.a2)
fmt.Println(c.b1)
fmt.Println(c.b2)
fmt.Println(c.A.a1)
fmt.Println(c.A.a2)
fmt.Println(c.B.b1)
fmt.Println(c.B.b2)
fmt.Println(c.int)
}
//a1
//10
//b1
//20
//a1
//10
//b1
//20
//888
7、嵌套匿名结构体后,可以在创建结构体变量时直接指定各个匿名结构体字段的值;
8、嵌入匿名结构体的指针也是可以的;
9、结构体的字段可以是结构体类型的。
package main
import (
"fmt"
)
type A struct{
a1 string
a2 int
}
type B struct{
b1 string
b2 int
}
type C struct{
A
B
int
}
type D struct{
a int
b B
}
func main(){
d := D{11, B{"BB", 66}}
fmt.Println(d)
fmt.Println(d.b.b1)
}
// {11 {BB 66}}
// BB
四、多态
变量、实例具有多种形态。面向对象的第三大特征,在golang中,多态是通过接口实现的,可以按照统一的接口来调用不同的实现,这时接口变量就呈现不同的形态。
package main
import (
"fmt"
)
type Chinese struct{
}
type American struct{
}
type SayHello interface {
say()
}
func (c Chinese) say(){
fmt.Println("中国人说中文")
}
func (a American) say(){
fmt.Println("美国人说英文")
}
func greet(s SayHello){
s.say()
}
func main(){
c := Chinese{}
a := American{}
greet(c)
greet(a)
}
//中国人说中文
//美国人说英文
接口体现多态特征:
1、多态参数:s叫多态参数
func greet(s SayHello){
s.say()
}
2、多态数组
var arr [3]SayHello
arr[0] = Chinese{"丽丽"}
arr[1] = Chinese{"菲菲"}
arr[2] = American{"Rose"}
fmt.Println(arr)
package main
import (
"fmt"
)
type Chinese struct{
name string
}
type American struct{
name string
}
type SayHello interface {
say()
}
func (c Chinese) say(){
fmt.Println("中国人说中文")
}
func (a American) say(){
fmt.Println("美国人说英文")
}
func greet(s SayHello){
s.say()
}
func main(){
var arr [3]SayHello
arr[0] = Chinese{"丽丽"}
arr[1] = Chinese{"菲菲"}
arr[2] = American{"Rose"}
fmt.Println(arr)
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南