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 ...
随机推荐
- 【C#】ORM框架
ORM提供了实现持久化层的另一种模式,它采用映射元数据来描述对象关系的映射,使得ORM中间件能在任何一个应用的业务逻辑层和数据库层之间充当桥梁. Java典型的ORM框架有个:Hibernate,my ...
- Web Server Jexus配置及使用
Web Server Jexus配置及使用 一.jexus概念: Jexus 即 Jexus Web Server,简称JWS,是Linux平台上的一款ASP.NET WEB服务器,是 Linux. ...
- B - Factors of Factorial
Problem Statement You are given an integer N. Find the number of the positive divisors of N!, modulo ...
- bzoj3328: PYXFIB(单位根反演+矩阵快速幂)
题面 传送门 题解 我们设\(A=\begin{bmatrix}1 & 1 \\ 1 & 0\end{bmatrix}\),那么\(A^n\)的左上角就是\(F\)的第\(n\)项 所 ...
- 洛谷P2900 [USACO08MAR]土地征用Land Acquisition(斜率优化)
题意 约翰准备扩大他的农场,眼前他正在考虑购买N块长方形的土地.如果约翰单买一块土 地,价格就是土地的面积.但他可以选择并购一组土地,并购的价格为这些土地中最大的长 乘以最大的宽.比如约翰并购一块3 ...
- django 基础框架学习 (二)
Django框架基础-02 Django缓存cookie 1.说明 当我们服务器在响应数据的同时,希望写⼊⼀些缓存数据到客户端 我们可以选择在响应的同时,将要写⼊到客户端的 ...
- mybatis 批量update两种方法对比
<!-- 这次用resultmap接收输出结果 --> <select id="findByName" parameterType="string&qu ...
- luogu4240 毒瘤之神的考验(毒瘤乌斯反演)
link 题意:求出\(\sum_{i=1}^n\sum_{j=1}^m\varphi(ij)\),对998244353取模 多组数据,\(T\le 10^4,n,m\le 10^5\). 前置知识: ...
- 使用between and 作为查询条件
- vscode 注册表
Windows Registry Editor Version 5.00 ; Open files [HKEY_CLASSES_ROOT\*\shell\Open with VS Code] @=&q ...