Golang 面向对象编程思想
1.抽象
在定义一个结构体的时候,实际上就是把一类事物的共有的属性和行为提取出来,行成一个物理模型。这种研究问题的方法称为抽象。
面向对象编程的三大特性:
Golang仍然有面向对象编程的继承,封装和多态特性,只是实现的方式和其他OOP语言不一样,Golang的三大特性是如何实现?
- 封装
1)将结构体、字段(属性)的首字母小写(不能导出,其他包不能使用,类似private)
2)给结构体所在包提供一个工厂模式的函数,首字母大写。类似一个构造函数
3)提供一个首字母大写的Set方法(类似其他语言的public),用于对属性判断并赋值
func(var 结构体类型名) SetXxx(参数列表) (返回值列表){
//加入数据验证的业务逻辑
var.字段= 参数
}
4)提供一个首字母大写的Get方法(类似其他语言的public),用于获取属性的值
func(var 结构体类型名) GetXxx(){
return var.字段
}
特别说明:在Golang开发中并没有特别强调封装,Golang本身对面向对象的特性做了简化。
2.封装
1)创建一个model的包,在包中创建一个person的结构体和相关方法,限制个别属性是否允许被其他包访问
package model import "fmt" //定义一个结构体 //Name 首字母大写,表示其他包可以直接访问 //age和sal 首字母小写,其他包是不能访问的 type person struct { Name string age int sal float64 } //写一个工厂模式的函数,相当于构造函数 func NewPerson(name string) *person { return &person{ Name: name, } } //为了访问age和sal我们编写一对SetXxx的方法和GetXxx的方法 func (p *person) SetAge(age int) { if age > 0 && age < 150 { p.age = age } else { fmt.Println("年龄范围不正确...") } } //获取年龄的Get方法 func (p *person) GetAge() int { return p.age } //SetSal方法 func (p *person) SetSal(sal float64) { if sal >= 3000 && sal <= 5000 { p.sal = sal } else { fmt.Println("薪水范围不正确...") } } //GetSal方法 func (p *person) GetSal() float64 { return p.sal }
2)创建一个main的包,在包中创建一个main方法用于访问model中的结构体
package main import ( "fmt" "src/main/src/go_code/chapter04/demo10/model" ) func main() { p := model.NewPerson("ckfuture") p.SetAge(18) p.SetSal(5000) fmt.Println(p) fmt.Println(p.Name, "age = ", p.GetAge(), " sal = ", p.GetSal()) }
运行如图:
代码结构:
3.继承
继承主要解决代码复用,让我们的编程更加靠近人类思维。
当多个结构体存在相同的属性(字段)和方法时,可以从这些结构体中抽象出结构体,在改结构体中定义这些相同的属性和方法。
其他的结构体不需要重新定义这些属性和方法,只需要嵌套一个匿名结构体即可。
也就是说:在Golang中,如果一个struct嵌套了另一个匿名结构体,那么这个结构体可以直接访问匿名结构体的字段和方法,从而实现了继承特性。
嵌套匿名结构体的基本语法:
type Goods struct{ Name string Price int } type Book struct{ Goods//这里就是嵌套匿名结构体Goods Writer string }
注意:结构体嵌入两个(或多个)匿名结构体,如两个匿名结构体有相同的字段和方法(同时结构体本身没有同名的字段和方法),在访问时,就必须名曲指定匿名结构体名字,否则编译报错。
Name string Age int } type B struct{ Name string score int } type C struct{ A B }
多重继承
如果一个struct嵌套了多个匿名结构体,那么改结构体可以直接访问嵌套的匿名结构体的字段和方法,从而实现了多重继承。
1)如嵌入的匿名结构体有相同的字段名或者方法名,则在访问时,需要通过匿名结构体类型名来区别
2)为了保证代码的简洁性,建议不使用多重继承。
4.接口(interface)
基本介绍
interface类型可以定义一组方法,但是这些不需要实现,并且interface不能包含任何变量,到某个自定义类型要使用的时候,在根据具体情况把这些方法写出来。
基本语法
type 接口名 interface{ method1(参数列表) 返回值列表 method2(参数列表) 返回值列表 }
实现接口所有方法
func(t 自定义类型) method1(参数列表) 返回值列表{ //方法实现 } func(t 自定义类型) method2(参数列表) 返回值列表{ //方法实现 }
小结说明:
1)接口里的说有方法都没有方法体,即接口的方法都时没有实现的方法,接口体现了程序设计的多态和高内聚低耦合的思想。
2)Golang中的接口,不需要显式的实现,只要一个变量,含有接口类型中的所有方法,那么这个变量就实现这个接口。因此,Golang中没有implement这样的关键字。
面向方法名实现接口
//声明一个接口 type Usb interface{ Start() Stop() } type Phone struct{ } //让Phone实现Usb的接口的方法 func (p Phone) Start(){ fmt.Println("Phone is running~") } func (p Phone) Stop(){ fmt.Println("Phone is Stoping~") }
接口注意事项
1)接口本身不能创建实例,但是可以指向一个实现了该接口的自定义类型的变量
2)接口中所有的方法都没有方法体,即都是没有实现的方法。
3)在Golang中,一个自定义类型需要将某个接口的所有方法都实现,我们说这个自定义类型实现了该接口。
4)一个自定义类型只有实现了某个接口,才能将该自定义类型的实例(变量)赋给接口类型。
5)只要是自定义数据类型,就可以实现接口,不仅仅是结构体类型。
6)一个自定义类型可以实现多个接口
7)Golang接口中不能有任何变量
8)一个接口(比如A接口)可以继承多个接口,这时如果要实现A接口,也必须将B,C接口的方法也全部实现。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!