Golang笔记(二)面向对象的设计
Golang笔记(二)面向对象的设计
Golang本质还是面向过程的语言,但它实现了一些OOP的特性,包括抽象、封装、继承和多态。
抽象和封装
Golang和C语言一样以struct为数据结构核心,不同的是Golang的struct可以定义自己的函数,这使得struct有了一些class的特点,所以Golang具有OOP里抽象和封装的概念。举个栗子来说,f是os.OpenFile()函数返回的File类型指针,File结构体实现了Close()函数,通过f.Close()调用File结构体里的Close()函数。下面是File和其Close()函数的定义:
type File struct {
...
}
...
func (f *File) Close() error {
...
}
Embedding模拟继承
Golang提供一种称为组合(Composition)的方法实现类似继承的特性。本质上Golang并没有继承(extend)这个概念,Composition是通过在struct里进行嵌套包含的方式提供了类似继承的方法。Composition有两种形式:非匿名组合(has-a)和匿名组合(Pseudo is-a)。
has-a就是简单的struct包含,struct A里包含了struct B,通过A.B.Func()调用了B里的Func(),这种直接调用的方式并不让人觉得是继承。
Pseudo is-a即Golang的Embedding特性,通过在struct A里匿名字段来假装A从B里继承。
看如下栗子,来理解一下Golang的Embedding机制:
type A struct {
...
}
func (a *A) Func1() {
fmt.Printf("A Func1 is called")
}
func (a *A) Func2() {
fmt.Printf("A Func2 is called")
}
type B struct {
A //Embedded struct A
...
}
func (b *B) Func1() {
fmt.Printf("B Func1 is called")
}
func main() {
B.Func2() //B继承了A的Func2(),此处输出:A Func2 is called
B.Func1() //B重写了Func1(),此处输出:B Func1 is called
}
以上栗子说明Golang支持方法重写,但要注意它并不支持方法的重载。如下面代码A.Func2里调用a.Func1并不会被重载成B.Func1:
func (a *A) Func2() {
fmt.Printf("A Func2 is called")
a.Func1() //此处a还是A,并不会被重载为B
}
func main() {
B.Func2() //输出:A Func2 is called 和 A Func1 is called
}
除了不支持重载,Golang也不支持多继承。如struct C如果继承了struct A和struct B,必须显示引用A和B里的函数以区分其中相同的函数名。同样Embedding机制也不提供多态特性,在上面的栗子中将B类型变量赋值给A类型的变量会报编译错误。Golang并不符合面向对象中的一个重要基本原则--里氏代换原则(Liskov Substitution Principle LSP)。
所以,Golang只是模拟继承特性。
Interface实现多态
Golang通过interface提供了多态的功能。Golang的interface设计最牛逼之处在于,任何数据结构只要实现了interface所定义的函数,就自动实现了这个interface。相比c++或者java要在class里进行冗长的声明,Golang的这个设计大大简化了interface的定义方式。Golang通过"interface"关键字定义了一套接口。如下代码是package "io"里定义的Reader和Writer接口:
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
如下是一些常用的package的数据结构里实现的Reader和Writer接口:
- os.File.Read()和os.File.Write()
- strings.Reader.Read()
- bufio.Reader.Read()和bufio.Writer.Write()
- bytes.Buffer.Read()和bytes.Buffer.Write()
当然你也可以定义自己的数据结构实现Reader和Writer接口。这样的数据结构变量即可直接用于interface变量的赋值。通过下面这个栗子即可快速理解Interface的作用:
func myRead(r Reader) {
r.Read()
}
func main() {
f, err := os.Open("./file")
myRead(f) //use os.File as Reader Interface
r := strings.NewReader("this is a string")
myRead(r) //use strings.Reader as Reader Interface
}
综上,Golang实现了OOP的一些特性,使其易于面向对象的编程思路。
Golang笔记(二)面向对象的设计的更多相关文章
- Java基础学习笔记(二) - 面向对象基础
面向对象 一.面向对象概述 面向对象思想就是在计算机程序设计过程中,参照现实事物,将事物的属性特征.行为特征抽象出来,描述成计算机时间的设计思想.面向对象思想区别于面向过程思想,强调的是通过调用对象的 ...
- Java学习笔记(二) 面向对象---构造函数
面向对象---构造函数 特点 函数名与类名相同 不用定义返回值类型 不写return语句 作用 对象一建立,就对象进行初始化. 具体使用情况 class Student { Student(){ Sy ...
- [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计
源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...
- UML和模式应用学习笔记-1(面向对象分析和设计)
UML和模式应用学习笔记-1(面向对象分析和设计) 而只是对情节的记录:此处的用例场景为:游戏者请求掷骰子.系统展示结果:如果骰子的总点数是7,则游戏者赢得游戏,否则为输 (2)定义领域模型:在领域模 ...
- ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET MVC 学习笔记-6.异步控制器 ASP.NET MVC 学习笔记-5.Controller与View的数据传递 ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用 ASP.NET MVC 学习笔记-3.面向对象设计原则
ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, 1 <appSettin ...
- jQuery源码笔记(二):定义了一些变量和函数 jQuery = function(){}
笔记(二)也分为三部分: 一. 介绍: 注释说明:v2.0.3版本.Sizzle选择器.MIT软件许可注释中的#的信息索引.查询地址(英文版)匿名函数自执行:window参数及undefined参数意 ...
- 8.python笔记之面向对象基础
title: 8.Python笔记之面向对象基础 date: 2016-02-21 15:10:35 tags: Python categories: Python --- 面向对象思维导图 (来自1 ...
- AJax 学习笔记二(onreadystatechange的作用)
AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...
- 2018-2019-2 20175306实验二面向对象程序设计《Java开发环境的熟悉》实验报告
2018-2019-2 20175306实验二面向对象程序设计<Java开发环境的熟悉>实验报告 面向对象程序设计-1 实验要求: 参考:> http://www.cnblogs.c ...
随机推荐
- Aspose.Words CookieBook
Aspose.Words.dll 版本 13.1.0.0 [原创]Aspose.Words组件介绍及使用—基本介绍与DOM概述 插入分页符 DocumentBuilder builder = new ...
- MongoDB 分片2
mongodb 在windows下面进行分片 mongodb 更新很快,在做分片的时候,查找了不少文章,但是很多已经过时了.现在把我搭建的过程及命令分享给大家.我用的是最新版本windows版3.4. ...
- c#线程-线程同步
线程同步 上一篇介绍了如何开启线程,线程间相互传递参数,及线程中本地变量和全局共享变量区别. 本篇主要说明线程同步. 如果有多个线程同时访问共享数据的时候,就必须要用线程同步,防止共享数据被破坏.如果 ...
- java 乱码问题解决方案
java 乱码问题解决方案 一.tomcat: <Connector port="8080" maxThreads="150&qu ...
- JavaAppArguments示例
本实验要求编写一个程序,此程序从命令行接收多个数字,求和之后输出结果.一大难点是命令行参数都是字符串,必须先将其转化为数字,才能相加. 中心想法就是将求和数字转换为整型并依次相加. 程序流程图: pu ...
- Missing artifact com.oracle:ojdbc14:jar:10.2.0.4.0.jar的问题
今天往STS工具中导入一个maven项目,导入后发现pom.xml文件的<dependency>处报错:Missing artifact com.oracle:ojdbc14:jar:10 ...
- vue原理实现
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- How to grow up as a BA
简书 https://www.jianshu.com/p/8f62b5c7fe1b Thoughtworks https://mp.weixin.qq.com/s/n1hGAM2nUoLvkE5xuU ...
- atcoder 2579
You are taking a computer-based examination. The examination consists of N questions, and the score ...
- POJ1664 放苹果 (母函数)
放苹果 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 37515 Accepted: 23090 Description ...