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的影子; ...
随机推荐
- java 欢迎页 主页 设置为servlet的方法
[参考]Java Web 设置默认首页 [参考]设置servlet或action作为欢迎页面 1. 使用HTML<meta>标签跳转至servlet <META HTTP-EQUI ...
- Ubuntu 上多版本软件管理方法
https://linuxize.com/post/how-to-install-gcc-compiler-on-ubuntu-18-04/ sudo apt install software-pro ...
- qt 获取汉字拼音首字母
#include "mainwindow.h"#include "ui_mainwindow.h"#include <QDebug>#include ...
- springboot:非web启动
需要运行一些调度任务,但是又不想放到web容器中运行. 见红色代码: import java.util.concurrent.ThreadPoolExecutor; import org.spring ...
- 【Spring Cloud学习之一】微服务架构
一.网站架构模式发展 单体应用-->SOA-->微服务 1.分布式项目与项目集群分布式项目:根据业务需求进行拆分成N个子系统,多个子系统相互协作才能完成业务流程子系统之间通讯使用RPC远程 ...
- 【ARM-Linux开发】OpenACC并行编程实战笔记
今年运气比较好,学了cuda之后,了解到了gpu的另两种使用语言opencl和openacc, opencl(Open Computing Language ,开放计算语言)是面向异构系统的并行编程 ...
- InvokeMember 使用(转http://blog.csdn.net/gooer/article/details/2927113)
函数原型: public object InvokeMember(string, BindingFlags, Binder, object, object[]); ...
- 前端向后端获取数据的三种方法:ajax、axios、fetch
1.jQuery中的ajax get方法: $.ajax({ url:"v4/api/film/now-playing?t=1539401039415&page=1&coun ...
- C++四大特性之封装
C++四大特性 C++作为面向对象编程语言,具备面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)的四大特性.抽象,封装,继承,多态. 所谓抽象,就是对具 ...
- BJFU-217-基于链式存储结构的图书信息表的逆序存储
这道题可以用头插法创建列表,然后正常输出: #include<stdio.h> #include<stdlib.h> #define MAX 100 typedef struc ...