Go语言基础之面向对象编程中
1 Golang面向对象编程基本介绍
Golang仍然有面向对象编程的继承,封装和多态的特性,只是实现的方式和其它OPP语言不一样,随后分别介绍Golang对面向对象编程的三大特性是如何实现的。
2 面向对象编程-封装
2.1 封装介绍
封装(encapsulation)就是把抽象出的字段和对字段的操作封装在一起,数据被保护在内部,程序的其它包只有通过被授权的操作(方法)才能对字段进行操作。
2.2 封装的作用
用通俗的电视机来理解封装:电视机是由不同的零件组装在一起,具有将接收的信号显示在屏幕上功能;作为家电,其向用户展现的是对应的功能,用户不用考虑其内部是怎么实现,只要充分利用电视机所提供的功能即可。那么类比到程序中这样做有什么好处:
隐藏实现细节;
可以对数据进行验证,保证数据的安全。
2.3 Golang中的封装体现
对结构体中的属性进行封装
通过方法和包实现封装
2.4 封装实现步骤
Golang中封装实现步骤:
将结构体、字段(属性)的首字母小写(其它包不能使用,类似private);
给结构体所在包提供一个工厂模式的函数(构造函数),首字母大小;
提供一个首字母大写的
Set
方法(类似其他语言的public),用于对属性判断并赋值 ,Set
方法的结构如下:
func (var 结构体类型名) SetXxx(参数列表) (返回值列表) {
//加入数据验证的业务逻辑
var.字段 = 参数
}
- 提供一个首字母大写的
Get
方法(类似其他语言的public),用于获取属性值,Get
方法的结构如下:
func (var 结构体类型名) GetXxx(参数列表) (返回值列表) {
return var.字段
}
另外,在Golang开发中并没有特别强调封装,Golang本身对面向对象的特性做了简化。
2.5 封装案例
需求:设计一个person
结构体,不能随便查看person
的年龄、工资等隐私,并对输入的年龄进行合理的验证。
设计:model包(person.go
实现person
结构体),main包(main.go
调用peron
结构体)。
代码实现:
//model/person.go
package model
//定义一个person的结构体
type person struct {
Name string
age int
sala float64
}
//写一个工厂模式函数,类似构造函数
func NewPerson(name string) *person {
return &person{
Name : name
}
}
//为了访问age 和 sala,以age字段为例编写对应的SetXxx和GetXxx方法
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
}
//main/main.go 导入model包
func main() {
p := model.NewPerson("tom")
p.SetAge(20)
fmt.Println(p)
fmt.Pritnln(p.Name, "age=", p.GetAge())
}
3 面向对象编程-继承
3.1 继承介绍
在现实中,一些事物有其共性,比如大学生、小学生都具有学生共有的属性和方法,那么我们可以将这些共同的属性和方法抽象出结构体并让大学生和小学生继承这些属性和方法,这样可以减少一些重复定义重复使用的工作。
继承可以提高代码复用、扩展性和维护性,让编程更加靠近人类思维。当多个结构体存在相同的属性和方式时,可以从这些结构体中抽象出结构体,在该结构体中定义这些相同的属性和方法。对于其他结构体不需要重新定义这些属性和方法,只需嵌套一个匿名结构体即可。以学生、大学生以及小学生为例,示意图如下:
在Golang中,如果一个struct
嵌套了另一个匿名结构体,那么这个结构体可以直接访问匿名结构体的字段和方法,从而实现了继承特性。
3.2 嵌套匿名结构体的基本语法
//以书籍继承货物为例
type Goods struct {
Name string
Price float64
}
type Book struct {
Goods //嵌套匿名结构体Goods
Writer string
}
3.3 继承细节及注意事项
结构体可以使用嵌套匿名结构体所有的字段和方法,即:首字母大写或小写的字段、方法都可以使用,示例如下:
type A struct {
Name string
age int
}
func (a *A) SayOk() {
fmt.Println("A SayOk", a.Name)
}
func (a *A) hello() {
fmt.Println("A hello", a.Name)
}
type B struct {
A
}
func main() {
var b B
b.A.Name = "tom"
b.A.SayOk()
b.A.hello()
}
匿名结构体字段访问可以简化:
func main() {
var b B
b.A.Name = "tom"
b.A.SayOk()
b.A.hello()
b.Name = "viktor"
b.SayOk()
b.hello()
}
/*
当直接通过b访问字段或方法时,比如b.Name:
编译器会先看b对应的类型有没有Name,如果有,则直接调用B类型的Name字段;
如果没有就去找B中嵌套的匿名结构体A有没有声明Name字段,如果有就调用;
没有的话继续查找,如果都找不到就报错
*/
当结构体和匿名结构体有相同的字段或者方法时,编译器采用就近访问原则访问,如果希望访问匿名结构体的字段和方法,可以通过匿名结构体名来区分;
结构体嵌入两个(或多个)匿名结构体,如两个匿名结构体有相同的字段和方法(同时结构体本身没有同名的字段和方法),在访问时,就必须明确指定匿名结构体名字,否则编译报错;
type A struct {
Name string
age int
}
type B struct {
Name string
Score float64
}
type C struct {
A
B
}
func main() {
var c C
//c.Name = "tom" //报错
c.A.Name = "tom"
fmt.Println(c)
}
如果一个struct
嵌套了一个有名结构体,这种模式就是组合,如果是组和关系,那么在访问组和的结构体的字段或方法时,必须带上结构体的名字;
type D struct {
a A
}
func main() {
var d D
d.a.Name = "viktor"
}
嵌套匿名结构体后,也可以在创建结构体变量时,直接指定各个匿名结构体字段的值;
type Goods struct {
Name string
Price float64
}
type Brand struct {
Name string
Address string
}
type TV struct {
Goods
Brand
}
type TV2 struct {
*Goods
*Brand
}
func main() {
tv := TV{Goods{"001", 5000.88}, Brand{"长虹","四川"},}
tv2 := TV{
Goods{
Price : 5000,
Name : "002",
},
Brand{
Name : "海尔"
Address : "山东"
},
}
fmt.Println("tv", tv)
fmt.Println("tv2", tv2)
tv3 := TV{&Goods{"003", 5000.88}, &Brand{"创维","河南"},}
tv4 := TV{
&Goods{
Price : 5000,
Name : "004",
},
&Brand{
Name : "夏普"
Address : "北京"
},
}
fmt.Println("tv3", *tv3.Goods, *tv3.Brand)
fmt.Println("tv4", *tv4.Goods, *tv4.Brand)
}
3.4 多重继承
如果一个struct
嵌套了多个匿名结构体,那么该结构体可以直接访问嵌套的匿名结构体的字段和方法,从而实现了多重继承。
在3.3中最后一个示例中,TV
就是一个多重继承的结构体,继承了Goods
,Brand
两个结构体。
多重继承注意事项:
- 如果嵌入的匿名结构体有相同的字段名或者方法名,则在访问时,需要通过匿名结构体类型名来区分;
- 为了保证代码的简洁性,建议尽量不要使用多重继承。
4练习
使用面向对象的思维方式编写一个学生信息管理系统:
- 学生有id、姓名、年龄、分数等信息;
- 程序提供展示学生列表、添加学生、编辑学生信息、删除学生等功能。
Go语言基础之面向对象编程中的更多相关文章
- 2018.3.5 Java语言基础与面向对象编程实践
Java语言基础与面向对象编程实践 第一章 初识Java 1.Java特点 http://www.manew.com/blog-166576-20164.html Java语言面向对象的 Java语言 ...
- ndk学习之c++语言基础复习----面向对象编程
关于面向对象编程对于一个java程序员那是再熟悉不过了,不过对于C++而言相对java还是有很多不同点的,所以全面复习一下. 类 C++ 在 C 语言的基础上增加了面向对象编程,C++ 支持面向对象程 ...
- 2018.6.20 Java考试试题总结(Java语言基础与面向对象编程)最新版
Java考试试题总结 一.单选题(每题1分 * 50 = 50分) 1.java程序的执行过程中用到一套JDK工具,其中javac.exe指( B ) A.java语言解释器 B.java字节码编译器 ...
- Java基础-初识面向对象编程(Object-Oriented-Programming)
Java基础-初识面向对象编程(Object-Oriented-Programming) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Java是一门面向对象的程序设计语言.那么什 ...
- 02_python基础(面向对象编程)
面向对象编程: 把一组数据结构和处理它们的方法组成对象(object),把相同行为的对象归纳为类(class),通过类的封装(encapsulation)隐藏内部细节,通过继承(inheritance ...
- C#中面向对象编程中的函数式编程详解
介绍 使用函数式编程来丰富面向对象编程的想法是陈旧的.将函数编程功能添加到面向对象的语言中会带来面向对象编程设计的好处. 一些旧的和不太老的语言,具有函数式编程和面向对象的编程: 例如,Smallta ...
- GO学习-(19) Go语言基础之网络编程
Go语言基础之网络编程 现在我们几乎每天都在使用互联网,我们前面已经学习了如何编写Go语言程序,但是如何才能让我们的程序通过网络互相通信呢?本章我们就一起来学习下Go语言中的网络编程. 关于网络编程其 ...
- C# 实例解释面向对象编程中的单一功能原则
在面向对象编程中,SOLID 是五个设计原则的首字母缩写,旨在使软件设计更易于理解.灵活和可维护.这些原则是由美国软件工程师和讲师罗伯特·C·马丁(Robert Cecil Martin)提出的许多原 ...
- C# 实例解释面向对象编程中的开闭原则
在面向对象编程中,SOLID 是五个设计原则的首字母缩写,旨在使软件设计更易于理解.灵活和可维护.这些原则是由美国软件工程师和讲师罗伯特·C·马丁(Robert Cecil Martin)提出的许多原 ...
随机推荐
- 聊一聊 InnoDB 引擎中的索引类型
索引对数据库有多重要,我想大家都已经知道了吧,关于索引可能大家会对它多少有一些误解,首先索引是一种数据结构,并且索引不是越多越好.合理的索引可以提高存储引擎对数据的查询效率. 形象一点来说呢,索引跟书 ...
- Vmware Ubuntu18.04更换清华源
一.安装Ubuntu18.04 省略 二.安装VmwareTool 1.选择机器右击安装2.打开文件,copy压缩文件到其它目录(理由: 内存不够解压)3.解压文件,运行./忘记名字了.pl文件4.注 ...
- 初探ASP.NET Core 3.x (4) - 项目的重要组成
目录 O 前请提要 I 启动部分 I.1 Program类 I.2 Startup类 I.2.1 这个类干什么呢?? I.2.2 特征?? I.3 appsettings.json I.4 launc ...
- Java入门 - 高级教程 - 02.集合
原文地址:http://www.work100.net/training/java-collection.html 更多教程:光束云 - 免费课程 集合 序号 文内章节 视频 1 概述 2 集合接口 ...
- [bzoj5507] [洛谷P5305] [gzoi2019]旧词
Descriptioin 浮生有梦三千场 穷尽千里诗酒荒 徒把理想倾倒 不如早还乡 温一壶风尘的酒 独饮往事迢迢 举杯轻思量 泪如潮青丝留他方 --乌糟兽/愚青<旧词> 你已经解决了五个问 ...
- RabbitMQ入门(三)订阅模式
在之前的文章RabbitMQ入门(二)工作队列中,我们创建了一个工作队列.工作队列背后的假设是每一项任务都被准确地传送至一个worker.在本文中,我们将会做一些不同的事情--我们将会把一个消息发 ...
- php--->把json传来的stdClass Object类型转array
php把json传来的stdClass Object类型转array 1.Php中stdClass.object.array的概念 stdClass是PHP的一个基类,即一个空白的类,所有的类几乎都继 ...
- 强大的Guava中的新集合类型: Multiset, Multimap, BiMap, Table, ClassToInstanceMap, RangeSet, RangeMap等
一 Multiset /** * 新类型集合: Multiset: Multiset就是可以保存多个相同的对象,并且无序 * 占据了List和Set之间的一个灰色地带 * 其他实现: TreeMult ...
- Kubernetes学习(二)
二 POD生命周期 initC作用说明 initC举例说明 init-pod.yaml apiVersion: v1kind: Podmetadata: name: myapp-pod labels: ...
- supervisor守护filebeat服务进程
1.变更原因 部署安装supervisor进行filebeat守护及后面的各种服务进程守护可以用2.变更内容增加supervisor服务 3.变量时间:6月2号-6月3号4.变更风险评估:无风险4.1 ...