Go 面向对象三大特性
#### Go 中面向对象的三大特性
上周因为有一些事情,停更了; 停更的这段时间,花了点时间做了一个小项目(https://github.com/yioMe/node_wx_alipay_personalPay)
原项目由node.js 写的,根据文档用Go 重写了(Gin + MySQL) ;
1. 没有了繁琐的node安装;
2. 没有 DB 迁移;
3. 支付成功回调优化;
4. 性能提升;
5. 修复了上传二维码不能识别的问题;
不过只重写了一小部分功能,应对日常个人支付不成问题,如有需要了解的朋友,私聊一同交流学习;
---
言归正传,Go 中的面向对象的特性与传统的OOP 语言不同,我们来一一学习了解;
###### 封装
封装就是把抽象的字段的对字段的操作封装在一起,数据被保护在内部,程序中的其它包只能通过被授权的操作才能对
字段操作;
封装的好处:
1. 隐藏实现的细节;
2. 可以对数据进行验证,保证数据的安全合理;
---
封装实现的步骤:
1. 将结构体,字段的首字母小写,不能被导出,其它包不能使用,类似JAVA 的private ;
2. 在结构体所在的包提供一下工厂模式的函数,首写字母大写,类似构造函数;
3. 提供一个首字母大写的Set 方法,用于对属性的判断并赋值
4. 提供一个首字母大写的Get 方法,用于获取属性的值;
5. 在Go 中没有特别强调封装,所以有其它编程语言的朋友,不需要用其它的语法特性来学习Go, 每种编程语言都有各自的特点;
package model import "fmt" type student struct {
Name string
age int // 其它的包不能直接访问
score float64 // 其它的包不能直接访问
} // 工厂方法,相当于构造函数
func NewStudent(name string) *student{
return &student{
Name:name,
}
}
// 为了访问和更改结构体的属性,编写一对GetXxx/SetXxx 的方法
// this 只是接收类型的名称, 可以命名为任意合法的标识符
func (this *student) GetAge() int {
return this.age
}
func (this *student) SetAge(age int){
// 可以在Set 方法里对数据进行校验
if age < 0 || age > 100 {
fmt.Println("age is wrong")
return
}
this.age = age
}
func (this *student) GetScore() float64{
return this.score
}
func (this *student) SetScore(score float64) {
if score < 0 || score > 100 {
fmt.Println("score is wrong")
return
}
this.score = score
}
package main import (
"fmt"
"personalPayment/model"
) func main(){
p := model.NewStudent("jack")
p.SetAge(20)
p.SetScore(200)
fmt.Println(*p)
fmt.Println(p.Name,"age=",p.GetAge(),"score=",p.GetScore())
}
---
###### 继承
1. 继承可以解决代码的复用问题
2. 当多个结构体有相同的属性和方法时,可以从这些结构体中抽象一下基础的结构体,在该结构体中定义相同的属性和方法;
3. Go 中实现继承是通过结构体匿名嵌套来实现;
基本语法:
type Person struct {
Name string
Age int
}
type Student struct {
Person // 嵌套的结构体,实现继承
Score float64
}
案例:
package model import "fmt"
type person struct {
Name string
age int
}
type student struct {
person
score float64 // 其它的包不能直接访问
}
type teacher struct {
person
class string
} // 学生的工厂方法,相当于构造函数
func NewStudent(name string) *student{
return &student{ person:person{
Name:name,
},
}
}
// 老师的工厂方法
func NewTeacher(name string) *teacher{
return &teacher{person:person{
Name:name,
}}
}
// 基础结构的公众方法
func (this *person) GetAge() int {
return this.age
}
func (this *person) SetAge(age int){
// 可以在Set 方法里对数据进行校验
if age < 0 || age > 100 {
fmt.Println("age is wrong")
return
}
this.age = age
}
// 学生的方法
func (this *student) GetScore() float64{
return this.score
}
func (this *student) SetScore(score float64) {
if score < 0 || score > 100 {
fmt.Println("score is wrong")
return
}
this.score = score
}
// 老师的方法
func (this *teacher) GetClass() string {
return this.class
}
func (this *teacher) SetClass(class string){
this.class = class
}
package main import (
"fmt"
"personalPayment/model"
) func main(){
s := model.NewStudent("jack")
// 调用公用的结构体方法
s.SetAge(20)
// 调用自己的方法
s.SetScore(100)
fmt.Println(s.Name,s.GetAge(),s.GetScore())
t := model.NewTeacher("tom")
// 调用公用的结构体方法
t.SetAge(40)
// 调用自己的方法
t.SetClass("English")
fmt.Println(t.Name,t.GetAge(),t.GetClass())
}
继承的使用和注意事项
1. 结构体可以使用嵌套匿名的结构体中的所有的属性和方法,不论大写与小写
2. 结构体中匿名结构体的字段和方法可以简化;
3. 当结构体和匿名结构体有相同的属性和方法时,编译器采用就近原则,如果需要访问匿名结构体中的字段
和方法需要通过匿名结构体的名称来区分;
4. 如果一个结构体嵌套了一个有名称的结构体,这种模式称为组合,在访问组合的结构体或方法时需要加上结构体的名字;
package main import (
"fmt"
) type person struct {
Name string
Age int
skill string
}
type student struct {
person
score float64
}
func (p *person) Say(){
fmt.Println("I am a person")
}
func (p *person) Do(){
fmt.Println("I am doing something")
} type A struct {
Name string
}
type B struct {
A
Name string
}
type C struct {
Name string
}
type D struct {
c C
Age int
}
func main(){
s := &student{}
s.person.Say()
s.person.Do()
s.person.Name = "jack"
s.person.Age = 20
s.person.skill = "speak"
fmt.Println(*s)
// 对匿名结构体中的属性方法可以简化为
s.Say()
s.Do()
s.Name = "jack2"
s.Age = 21
s.skill = "laugh"
fmt.Println(*s)
// 如果结构体和匿名结构体中有相同的属性或方法,编译器将采用就近原则,
// 如果需要访问匿名结构体的属性和方法需要通过匿名结构体的名称
a := B{
A: A{
Name:"aaa",
},
Name:"bbb",
}
fmt.Println(a.Name) // bbb
fmt.Println(a.A.Name) // aaa
// 对于组合,在访问继承结构体的方法或属性时需要加上结构体的名称
d := D{
c:C{Name:"ccc"},
Age:20,
}
fmt.Println(d.Age) // 自己的属性
fmt.Println(d.c.Name) // 访问继承的属性
}
个人微信公众号上有最新文章,欢迎关注一同交流学习
Go 面向对象三大特性的更多相关文章
- [.net 面向对象编程基础] (11) 面向对象三大特性——封装
[.net 面向对象编程基础] (11) 面向对象三大特性——封装 我们的课题是面向对象编程,前面主要介绍了面向对象的基础知识,而从这里开始才是面向对象的核心部分,即 面向对象的三大特性:封装.继承. ...
- [.net 面向对象编程基础] (12) 面向对象三大特性——继承
[.net 面向对象编程基础] (12) 面向对象三大特性——继承 上节我们说了面向对象的三大特性之一的封装,解决了将对同一对象所能操作的所有信息放在一起,实现统一对外调用,实现了同一对象的复用,降低 ...
- [.net 面向对象编程基础] (13) 面向对象三大特性——多态
[.net 面向对象编程基础] (13) 面向对象三大特性——多态 前面两节,我们了解了面向对象的的封装和继承特性,面向对象还有一大特性就是多态.比起前面的封装和继承,多态这个概念不是那么好理解.我们 ...
- 面向对象编程(九)——面向对象三大特性之继承以及重写、Object类的介绍
面向对象三大特性 面向对象三大特征:继承 :封装/隐藏 :多态(为了适应需求的多种变化,使代码变得更加通用!) 封装:主要实现了隐藏细节,对用户提供访问接口,无需关心方法的具体实现. 继承:很好的实现 ...
- C++面向对象三大特性
面向对象三大特性 继承 public protected private public继承 public protected 不可见 private继承 private private 不可见 pro ...
- JAVA基础——面向对象三大特性:封装、继承、多态
JAVA面向对象三大特性详解 一.封装 1.概念: 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问. 2.好处: 只能通过规定的方法访问数据. ...
- day20面向对象三大特性 , 类嵌套
#!/usr/bin/env python# -*- coding:utf-8 -*- # 1.简述面向对象三大特性并用代码表示."""封装:class Account: ...
- python 面向对象(三大特性)
python 面向对象(初级) (思维导图 ↑↑↑↑↑) 概述: 面向过程:根据业务逻辑从上到下垒代码. 函数式:将某功能代码封装至函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类 ...
- python 面向对象三大特性(封装 多态 继承)
今天我们来学习一种新的编程方式:面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)注:Java和C#来说只支持面向对象编程,而python比较灵活即支持面 ...
- python面向对象三大特性
面向对象的三大特性: 封装.继承和多态 一.封装 封装,顾名思义就是将内容封装到某个地方,以后可以直接调用被封装到某处的内容. - 将内容封装到某处 - 从某处调用被封装的内容 第一步,将内容封装到某 ...
随机推荐
- 【LeetCode】1033. Moving Stones Until Consecutive 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 脑筋急转弯 日期 题目地址:https://leet ...
- 【LeetCode】268. Missing Number 解题报告(Java & Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 求和 异或 日期 题目地址:https://leet ...
- 使用Java对接永中格式转换
永中格式转换服务基于永中DCS的文档转换能力,支持不同格式文件之间的高质量互转,可实现PDF文档与Word.Excel.PPT.图片的高质量互转,PDF文档转换完美保留原文档的版式,格式等,转换效果出 ...
- sql-labs 1-14
less-1: 1.采用二分法进行猜列: http://192.236.147.191:30000/Less-1/?id=1' order by 10--+ Welcome Dhakkan Un ...
- 实战!Spring Boot 整合 阿里开源中间件 Canal 实现数据增量同步!
大家好,我是不才陈某~ 数据同步一直是一个令人头疼的问题.在业务量小,场景不多,数据量不大的情况下我们可能会选择在项目中直接写一些定时任务手动处理数据,例如从多个表将数据查出来,再汇总处理,再插入到相 ...
- Are Loss Functions All the Same?
目录 概 主要内容 一些假设 损失函数 损失函数的统计性质 收敛速度 分类的界 Rosasco L, De Vito E, Caponnetto A, et al. Are loss function ...
- 初遇NFT-IPFS
初遇NFT-IPFS 本次学习如何使用Hardhat框架制作可预售的NFT并利用IPFS存储元数据. NFT简介 NFT全称Non-fungible Token(即非同质化通证).不可分割性(目前有碎 ...
- Spring练习,使用注解的方式,完成模拟用户的正常登录。要求如下: 使用注解方式开发模拟用户的正常登录。
相关 知识 >>> 相关 练习 >>> 实现要求: 在该实践案例中,使用注解的方式,完成模拟用户的正常登录. 要求如下: 使用注解方式开发模拟用户的正常登录. 实现 ...
- Java程序设计基础作业目录(作业笔记)
持续更新中............. Java程序设计基础笔记 • [目录] 我的大学笔记>>> 第1章 初识Java>>> 1.1.4 学生成绩等级流程图练习 1 ...
- Android物联网应用程序开发(智慧园区)—— 图片预览界面
效果图: 实现步骤: 1.首先在 build.gradle 文件中引入 RecycleView implementation 'com.android.support:recyclerview-v7: ...