GoLange:面向对象
学习自:Go教程130页
1、类定义
方式:结构体+方法
- 结构体:定义有哪些数据
- 方法:定义结构体的方法
例子:定义一个Person类
1 2 3 4 5 6 7 8 9 10 | //结构体定义人的属性 type Person struct { name string age int } //方法定义人的行为 func (p Person)Say(){ fmt.Println( "my name is" ,p.name, " my age is" ,p.age) } |
2、创建对象
1 | 对象名 := 结构体名{变量1,变量2,...} |
例子
1 2 3 4 | p1 := Person{ "lnj" ,33} p1.Say() p2 := Person{ "zs" ,18} p2.say() |
3、不同包中变量、函数、方法、类型的公私有问题
在Go中通过首字母大小写来控制公私有:
- 首字母小写——私有,仅在当前包中使用
- 首字母大写——公有,其他包中也可以使用
例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | //公有:其他包也可用 //私有:仅当前包可以用 var num1 int = 123 //私有 var Num1 int = 123 //公有 type person struct { //结构体 私有 name string age int } type Student struct { //公有 Name string Age int } func test1(){ //函数 私有 ... } func Test2(){ //公有 ... } func (p person)say(){ //方法 私有 ... } func (s Student)Say(){ //方法 公有 ... } |
4、面向对象三大特性及实现:继承、封装、多态
1)封装
说明
对外界隐藏数据特性,只暴露对数据操作相关的方法
实现
- 类-公有
- 类数据-私有
- 类方法-公有
例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package model type Person struct { //类名大写 公有 name string //数据小写 私有 age int } func (p *person)SetAge(age int){ //方法大写 公有 p.age=age; } //下文省略包名,Person和main分属不同包 func main(){ //不能直接在创建对象时就赋初值了 //错误写法 p := model.Person( "lnj" .18) //正确1 p := model.Person() p.SetAge(18) //正确2 p := new(model.Person) p.SetAge(18) |
2)继承
Go中继承是通过组合实现的
组合:
1 2 3 4 5 6 7 8 | type Person struct { ... } type Student struct { Person //继承了Person的特性 ... } |
①普通继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | type Person struct { name string age int } type Student struct { Person //Student继承了Person的特性 score int } type Teacher struct { Person //Teacher继承了Person的特性 Title string } //具体应用 func main(){ s := Student{<strong>Person{ "lnj" ,18}</strong>,99}<br> //输出继承的父类的属性,两种方法 s.Person.name s.name<br>} |
继承过程中出现了重名,则采用就近原则
例子:Person和Student中都有name属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | type Person struct { name string age int } type Student struct { Person name string score int } func main(){ s := Student{Person{ "zs" ,18}, "ls" ,99} s.name //Student自己的name即ls s.Person.name //父类的name即zs |
②多重继承
A→B→C
A→C←B
1 2 3 4 5 6 7 8 9 10 11 12 | type <strong>Object</strong> struct { life int } type <strong>Person</strong> struct { <strong> Object</strong> name string age int } type <strong>Student</strong> struct { <strong> Person</strong> score int } |
初始化
1 | s := Student{Person{Object{77}, "zs" ,33},99} |
访问
1 2 3 4 5 6 7 8 9 10 11 | //对于Object中无重名属性life,三种访问方式均可 s.life s.Person.life s.Person.Object.life //对于Person中无重名属性name age,有两种访问方式 s.age s.Person.age //对于Student独有属性score,只能通过它的对象访问 s.score |
③方法继承
一般继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | type Person struct { ... } //父类方法 func {p Person)say(){ ... } type Student struct { Person ... } func main(){ stu := Student{...} stu.say() //直接调用继承来的方法 } |
重写(子类和父类存在同名方法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | type Person struct { ... } //父类方法 func (p Person)say(){ ... } type Student struct { Person ... } func (s Student)say(){ ... } func main(){ stu := Student{...} <strong> stu.say() //直接调用,调用的是自己的方法 stu.Person.say() //对用父类方法</strong> } |
3)多态
多态:一个事物多种状态(一个事物既是它自己,又是它的父类)
Go中通过接口实现多态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | //定义接口Animal type Animal interface { Eat() } //定义两个具体的类Dog、Cat type Dog struct { name string age int } type cat struct { name string age int } //实现接口方法 func (d Dog)Eat(){...} func (c Cat)Eat(){...} //实现类特有方法 func (c Cat)Special(){...} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | func main(){ //1、生成接口对象 var a Animal; //2、灵活表现为不同的对象(需要是实现接口方法的类) a=Dog{ "旺财" ,18} a.Eat() a=Cat{ "喵喵" ,18} a.Eat() //3、调用对象特有方法 //但是只有对象才能调用自己的方法,接口无法调用接口中没有的方法,所以这里要用ok-idiom,断言机制 if cat,ok := a.(Cat);ok{ cat.Special() } } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性