golang面向对象实现
面向对象编程三大特点:封装、继承、多态。
1. 构造函数
Go不支持构造器。如果某类型的零值不可用,需要提供NewT(parameters)函数,用来初始化T类型的变量。按照Go的惯例,应该把创建T类型变量的函数命名为NewT(parameters),若一个包中只含有一种类型,则函数名为New(parameters)。
包含NewT()函数的包的结构体应该首字母小写,以使结构体对外不可引用,只能通过NewT()创建结构体。相应的,结构体内所有字段也应该小写,被隐藏,方法要根据实际情况确认。
// oop/employee/employee.go
package employee
import "fmt" type employee struct {
firstName string
lastName string
totalLeaves int
leavesTaken int
} func New(firstName string, lastName string, totalLeaves int, leavesTaken int) employee{
e := employee{firstName, lastName, totalLeaves, leavesTaken}
return e
} func (e employee) LeavesRemaining(){
fmt.Printf("%s %s has %d leaves remaining", e.firstName, e.lastName, e.totalLeaves-e.leavesTaken)
} //oop/main.go
package main
import "oop/employee" func main(){
/*
e := employee.Employee{
FirstName: "wang",
LastName: "qing",
TotalLeaves: 30,
LeavesTaken: 20,
}
*/
e := employee.New("wang", "qing", , )
e.LeavesRemaining()
}
2. 继承
Go不支持继承,但他支持组合(composition)。组合的一般含义定义为“合并在一起”。
一般通过嵌套结构体进行组合。
3. 多态
Go通过接口来实现多态。在Go中,一个类型如果定义了接口所声明的全部方法,那该类型就实现了该接口。
所有实现了接口的类型,都可以把它的值保存在一个接口类型的变量中。在 Go 中,我们使用接口的这种特性来实现多态。
4.面向接口
golang中面向对象编程更多的体现为面向接口。
接口 的作用其实就是为不同层级的模块提供了一个定义好的中间层,上游不再需要依赖下游的具体实现,充分地对上下游进行了解耦。
它为我们的程序提供了非常强的灵活性,想要构建一个稳定、健壮的 Go 语言项目,不使用接口是完全无法做到的。
单元测试是一个项目保证工程质量最有效并且投资回报率最高的方法之一,作为静态语言的 Go,想要写出覆盖率足够(最少覆盖核心逻辑)的单元测试本身就比较困难,因为我们不能像动态语言一样随意修改函数和方法的行为,而接口就成了我们的救命稻草,写出抽象良好的接口并通过接口隔离依赖能够帮助我们有效地提升项目的质量和可测试性。
如下代码其实就不是一个设计良好的代码,它不仅在 init 函数中隐式地初始化了 grpc 连接这种全局变量,而且没有将 ListPosts 通过接口的方式暴露出去,这会让依赖 ListPosts 的上层模块难以测试。
package post
var client *grpc.ClientConn
func init() {
var err error
client, err = grpc.Dial(...)
if err != nil {
panic(err)
}
}
func ListPosts() ([]*Post, error) {
posts, err := client.ListPosts(...)
if err != nil {
return []*Post{}, err
}
return posts, nil
}
可以使用下面的代码改写原有的逻辑,使得同样地逻辑变得更容易测试和维护:
package post
type Service interface {
ListPosts() ([]*Post, error)
}
type service struct {
conn *grpc.ClientConn
}
func NewService(conn *grpc.ClientConn) Service {
return &service{
conn: conn,
}
}
func (s *service) ListPosts() ([]*Post, error) {
posts, err := s.conn.ListPosts(...)
if err != nil {
return []*Post{}, err
}
return posts, nil
}
- 通过接口
Service暴露对外的ListPosts方法; - 使用
NewService函数初始化Service接口的实现并通过私有的结构体service持有 grpc 连接; ListPosts不再依赖全局变量,而是依赖接口体service持有的连接;
当我们使用这种方式重构代码之后,就可以在 main 函数中显式的初始化 grpc 连接、创建 Service 接口的实现并调用 ListPosts 方法:
package main
import ...
func main() {
conn, err = grpc.Dial(...)
if err != nil {
panic(err)
}
svc := post.NewService(conn)
posts, err := svc.ListPosts()
if err != nil {
panic(err)
}
fmt.Println(posts)
}
这种使用接口组织代码的方式在 Go 语言中非常常见,我们应该在代码中尽可能地使用这种思想和模式对外提供功能:
- 使用大写的
Service对外暴露方法; - 使用小写的
service实现接口中定义的方法; - 通过
NewService函数初始化Service接口;
当我们使用上述方法组织代码之后,其实就对不同模块的依赖进行了解耦,也正遵循了软件设计中经常被提到的一句话 — 『依赖接口,不要依赖实现』,也就是面向接口编程。
参考:
1.Go 系列教程(Golang tutorial series) go语言中文网
golang面向对象实现的更多相关文章
- golang面向对象和interface接口
一. golang面向对象介绍 1.golang也支持面向对象编程,但是和传统的面向对象编程有区别,并不是纯粹的面向对象语言.2.golang没有类(class),golang语言的结合体(struc ...
- Golang面向对象编程-struct(结构体)
Golang面向对象编程-struct(结构体) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是面向对象编程 面向对象编程(Object Oriented Program ...
- golang 面向对象编程
概述 Golang语言的面向对象与c++,py等语言有所不同,是由于Golang不支持继承:与上述支持聚合和继承的面向对象的语言不同,Golang只支持聚合(也叫做组合)和嵌入.聚合和嵌入的区别: t ...
- 【GoLang】golang 面向对象编程 & 面向接口编程
005.面向对象&接口编程 1 面向函数编程 1.1 将数据作为参数传递到函数入参 1.2 对象与函数是分离的 2 面向对象编程 2.1 使用者看起来函数作为对象的属性而非参数 2.2 函数属 ...
- golang面向对象分析
说道面向对象(OOP)编程, 就不得不提到下面几个概念: 抽象 封装 继承 多态 其实有个问题Is Go An Object Oriented Language?, 随便谷歌了一下, 你就发现讨论这个 ...
- golang面向对象初识
struct是变量的集合 interface是方法的集合 struct与interface都支持匿名字段, 换言之, 支持组合实现继承. golang的struct与C++的class一样, 只能声明 ...
- golang 面向对象
深入理解GO语言的面向对象_Golang_脚本之家 https://www.jb51.net/article/94030.htm 深入理解GO语言的面向对象 更新时间:2016年10月04日 10:4 ...
- Golang面向对象_继承
package main import "fmt" type Person struct { name string //名字 sex byte //性别 age int //年龄 ...
- Golang 中的 面向对象: 方法, 类, 方法继承, 接口, 多态的简单描述与实现
前言: Golang 相似与C语言, 基础语法与C基本一致,除了广受争议的 左花括号 必须与代码同行的问题, 别的基本差不多; 学会了C, 基本上万变不离其宗, 现在的高级语言身上都能看到C的影子; ...
随机推荐
- mysql查看连接情况
1.使用navicat进入命令行或者命令行进入mysql 2.看所有进程 show full processlist; 3.看所有连接show status like 'Threads%';
- 全文搜索引擎Elasticsearch详细介绍
我们生活中的数据总体分为两种:结构化数据 和 非结构化数据. 结构化数据:也称作行数据,是由二维表结构来逻辑表达和实现的数据,严格地遵循数据格式与长度规范,主要通过关系型数据库进行存储和管理.指具有固 ...
- java Random 带权重的随机选择
实际场景中,经常要从多个选项中随机选择一个,不过,不同选项经常有不同的权重. /** * Created by xc on 2019/11/23 * 带权重的随机选择 */ public class ...
- Vmvare v12下搭建Ubuntu操作系统-18.04-desktop-amd64.iso镜像环境
1.选择[典型],点击下一步. 2.找到ubuntu镜像文件所在位置,如图所示: 3.配置用户信息 4.设置安装位置 5.磁盘尽量大一些,笔者设置40g 6.自定义修改硬件信息 7.内存建 ...
- url、href、src
一.URL的概念 统一资源定位符(或称统一资源定位器/定位地址.URL地址等,英语:Uniform Resource Locator,常缩写为URL),有时也被俗称为网页地址(网址).如同在网络上的门 ...
- node.js执行shell命令进行服务器重启
nodejs功能强大且多样,不只是可以实现 服务器端 与 客户端 的实时通讯,另一个功能是用来执行shell命令 1.首先,引入子进程模块var process = require('child_pr ...
- [数据结构 - 第6章] 树之二叉平衡树(C语言实现)
一.什么是平衡二叉树? 平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两 ...
- [xsy3132]数表
题意:一个$n\times m$的数表,数值$\in[0,4)$,你可以任意次选择一行或一列$+1,\text{mod }4$,要最小化所有数的和 因为$n\leq10$,所以数表可以看成$m$个$n ...
- eclipse不提示
1.菜单window->Preferences->Java->Editor->Content Assist->Enable auto activation 选项要打上勾 ...
- JavaEE 期末总结
struts2部分 一.struts2框架的集成: 1.web.xml配置struts2过滤器:前端控制器.核心控制器 如果有多个过滤器,需要将该过滤器放置到最后一个 2.struts.xml配置:主 ...