把存货赶紧更新一波(捂脸)

1. 类型系统

类型系统,就是说一种编程语言怎么设计的它的类型的体系结构。

比如基础类型啊,复合类型啊,一些可以指向任意对象的类型啊,以及类型的语义,面向对象的特性,接口,这些内容。

2. 类型的方法

在Golang里,可以给任意类型添加方法。

比如:

type Integer int

func (i Integer)Less (b Integer) bool {
return a<b
}

Integer与int没有本质的不同。我们声明了一个属于Integer的函数Less()。这样我们就可以把整型当作普通的类来使用:

func main() {
var a Integer = 1
if a.Less(2) {
fmt.Println(a, "Less 2")
}
}

那么类型的方法到底是什么呢?我们把刚才的Less()和下面的方法做个对比:

func NewLess(a Integer, b Integer) bool {
return a<b
}

这里,我刻意没有把a和b写在一起。对比刚才的Less()方法,我们发现,所谓的类型方法,关键在于隐藏的this指针。如果我们把类型a放到传递参数的部分,我们就发现这两个函数并没有区别。

如果我们需要在类型方法中对类型的实例本身进行修改,那么在声明的时候,就需要声明成指针。这也很好理解,就跟传递参数的时候传递指针是一样的道理。

func (i *Integer)Less (b Integer) bool {
return a<b
}

关于成员函数,再加一个例子

type T struct {
num int
} func (t T) add1() {
t.num += 5
} func (t *T) add2() {
t.num += 5
} func main() {
t1 := T{5}
t2 := &T{5}
fmt.Println(t1)
fmt.Println(t2)
t1.add1()
fmt.Println(t1.num)
t1.add2()
fmt.Println(t1.num)
t2.add1()
fmt.Println(t2.num)
t2.add2()
fmt.Println(t2.num)
}

其结果如下:

shell> go run main.go
{5}
&{5}
5
10
5
10

3. 值语义和引用语义

值语义和引用语义的区别主要在于赋值。

b = a
b.Modify()

如果此时a没有变化,就是值类型,反之是引用类型。

Golang中大部分类型都是值类型。

所以只要记住引用类型即可。他们是切片,map,channel和接口。

4. 结构体和结构体的初始化

结构体struct跟其他语言的struct和class差不多。不过golang没有传统意义上的继承。

type Rect struct {
x, y float64
width, height float64
}

struct的实例的初始化方法如下:

rect1 := new(Rect)
rect2 := Rect{}
rect3 := Rect{0, 0, 100, 200}
rect4 := Rect{width: 100, height: 200}

需要注意的是,没有显式初始化的成员都会初始化为该类型的0值。

另外golang中没有构造函数的概念。如果需要类似的构造函数,通常是创建一个全局函数进行新对象的创建。

5. 结构体的组合

前面提到golang并没有传统意义上的继承,但是,golang提供了组合。

type Base struct {
Name string
} func (base *Base) Foo() {...}
func (base *Base) Bar() {...} type Foo struct {
Base
...
} func (foo *Foo) Bar() {
foo.Base.Bar()
...
}

可以看到,上面的代码定义了一个Base类,实现了Foo()和Bar()两个方法。然后定义了一个Foo类,该类中组合了Base类。

从形式了,Foo类“继承”了Base类,并改写了Bar()方法,同时在Bar()方法中调用了Base基类中的Bar()方法。

对于没有被改写的方法,就相当于是被“继承”了,同时仍然可以通过组合的类型来访问方法。比如,foo.Foo()和foo.Base.Foo()的效果是一致的。

6. 可见性

跟前面提到的相同,golang使用首字母大小写区别public和private。

7. 接口

Golang中的接口是非入侵式的。一个类只要实现了接口要求的所有函数,这个类就实现了该接口。

未完待续

Go语言学习笔记(3)——面向对象编程的更多相关文章

  1. javascript 学习笔记之面向对象编程(一):类的实现

    ~~想是一回事,做是一回事,写出来又是一回事~~一直以来,从事C++更多的是VC++多一些,从面向过程到面向对象的转变,让我对OO的编程思想有些偏爱,将一个客观存在的规律抽象出来总是让人比较兴奋,通过 ...

  2. python 学习笔记7 面向对象编程

    一.概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发"更快更好更强..." ...

  3. javascript 学习笔记之面向对象编程(二):继承&多态

    ~~接上篇~~上一篇实现了类的实现以及类成员变量和方法的定义,下面我们来了解下面向对象中两个最重要的特性:继承和多态. 继承 js中同样可以实现类的继承这一面向对象特性,继承父类中的所有成员(变量和属 ...

  4. 【c# 学习笔记】面向对象编程的应用

    在平时的开发过程中,面向对象编程的应用肯定必不可少.但前面的内容只是单独介绍了类.面向对象思想和接口,那么我们怎么在平时工作中来应用他们来实现面向对象编程呢? 如果你想设计一个Dog类,有了类的概念后 ...

  5. JavaSE学习笔记05面向对象编程01

    面向对象编程01 java的核心思想就是OOP 面向过程&面向对象 面向过程思想: 步骤清晰简单,第一步做什么,第二步做什么...... 面向过程适合处理一些较为简单的问题 面向对象思想: 物 ...

  6. C++ Primer 学习笔记_67_面向对象编程 --转换与继承、复制控制与继承

    面向对象编程 --转换与继承.复制控制与继承 I.转换与继承 引言: 由于每一个派生类对象都包括一个基类部分,因此能够像使用基类对象一样在派生类对象上执行操作. 对于指针/引用,能够将派生类对象的指针 ...

  7. C++ Primer 学习笔记_69_面向对象编程 --继承情况下的类作用域

    面向对象编程 --继承情况下的类作用域 引言: 在继承情况下,派生类的作用域嵌套在基类作用域中:假设不能在派生类作用域中确定名字,就在外围基类作用域中查找该名字的定义. 正是这样的类作用域的层次嵌套使 ...

  8. Spark学习笔记11面向对象编程

    面向对象编程   11.1 object类 11.1.1定义一个简单的类   11.1.2 field的getter与setter 定义类包含,定义类的field及方法.其格式如下 class Cla ...

  9. C++ Primer 学习笔记_72_面向对象编程 --句柄类与继承[续]

    面向对象编程 --句柄类与继承[续] 三.句柄的使用 使用Sales_item对象能够更easy地编写书店应用程序.代码将不必管理Item_base对象的指针,但仍然能够获得通过Sales_item对 ...

  10. python学习笔记(七):面向对象编程、类

    一.面向对象编程 面向对象--Object Oriented Programming,简称oop,是一种程序设计思想.在说面向对象之前,先说一下什么是编程范式,编程范式你按照什么方式来去编程,去实现一 ...

随机推荐

  1. 01 . Go之从零实现Web框架(框架雏形, 上下文Context,路由)

    设计一个框架 大部分时候,我们需要实现一个 Web 应用,第一反应是应该使用哪个框架.不同的框架设计理念和提供的功能有很大的差别.比如 Python 语言的 django和flask,前者大而全,后者 ...

  2. window10搭建pyspark(超级详细)

    一.组件版本说明 Java JDK:1.8.0_144 spark-2.4.3-bin-hadoop2.7hadoop-2.7.7 scala-2.12.8 hadooponwindows-maste ...

  3. python数据基本运算处理===循环

    一.循环语句 1.while while的循环条件为True,即每次正常循环完毕都会返回判断一次条件 只有读到break才能立刻彻底结束循环,break只能结束本层循环 continue也能立即结束本 ...

  4. 为Github仓库添加Github Actions实现持续集成: Android apk自动编译发布以及github pages同步推送coding.net

    内容转载自我的博客 目录 说明 1. 编写Android项目的CI配置文件 2. 编写Jekyll项目的CI配置文件 2.1 配置coding.net 2.2 配置github 2.3 自动部署到co ...

  5. Redis的sentinel(哨兵)部署

    1.准备文件 1.解压redis-4.0.1.tar.gz的redis文件 2.新建目录 redis-cluster以及子目录 master-6379 slave-7000 slave-7001 3. ...

  6. python virtualenv 基本使用

    下载 pip install virtualenv 校验是否成功 virtualenv --version 使用 创建env环境 要写一个新项目,使用env先创建环境 cd xx\xx\xx\ # 进 ...

  7. 【C++】《C++ Primer 》第十四章

    第十四章 重载运算与类型转换 一.基本概念 重载运算符是具有特殊名字的函数:由关键字operator和其后要定义的运算符号共同组成.也包含返回类型.参数列表以及函数体. 当一个重载的运算符是成员函数时 ...

  8. Flutter 布局类组件:层叠布局(Stack和Positioned)

    前言 层叠布局,即子组件可以根据距父容器四个角的位置来确定自身的位置.绝对定位运行子组件堆叠起来,即按照代码中声明的顺序. Flutter中使用Stack和Positioned这两个组件来配合实现绝对 ...

  9. Docker学习笔记之创建安装了nginx服务器的镜像

    操作步骤: 1. 编辑Dockerfile 2. 使用build命令创建镜像 3. 使用run命令测试创建的镜像 编辑Dockerfile 首先,需要使用文本编辑器编辑Dockerfile文件(注意没 ...

  10. mac配置Android SDK

    下载地址:http://tools.android-studio.org/index.php/sdk 2.找到tools文件夹 选中android-sdk-macosx包下的tools文件夹,按com ...