1.Golang语言面向对象编程说明
Golang
也支持面向对象编程(OOP)
,但是和传统的面向对象编程有区别,并不是纯粹的面向对象语言。所以我们说Golang
支持面向对象编程特性是比较准确的。Golang
没有类
(class),Go语言的结构体(
struct)
和其它编程语言的类(class)有同等的地位,你可以理解Golang
是基于struct
来实现OOP特性的。Golang
面向对象编程非常简洁,去掉了传统OOP语言的继承、方法重载、构造函数和析构函数、隐藏的this指针等等Golang
仍然有面向对象编程的继承,封装和多态
的特性,只是实现的方式和其它OOP语言不一样,比如继承:Golang
没有extends
关键字,继承是通过匿名字段
来实现。Golang
面向对象(OOP)很优雅,OOP本身就是语言类型系统(typesystem)的一部分,通过接口interface
关联,耦合性低,也非常灵活。后面同学们会充分体会到这个特点。也就是说在Golang
中面向接口编程是非常重要的特性
1.1 Golang中的struct
用来自定义复杂的数据结构
struct
里面可以包含多个字段(属性)struct
类型可以定义方法, 注意和函数的区分struct
类型是值类型struct
类型可以嵌套Go语言中没有
class
类型,只有struct
类型
1.2 struct的定义
struct
声明:
1 | type 标识符 struct{ |
例子:1
2
3
4
5type Student struct{
Name string
Age int
Score int
}
- 字段/属性
结构体字段=属性=field
字段是结构体的一个组成部分,一般是基本数据类型、数组,也可是引用类型。
字段声明语法同变量,示例:字段名字段类型
- 字段的类型可以为:基本类型、数组或引用类型
- 在创建一个结构体变量后,如果没有给字段赋值,都对应一个零值(默认值),规则同前面讲的一样:布尔类型是false,数值是0,字符串是””。
- 数组类型的默认值和它的元素类型相关,比如score[3] int则为[0,0,0]指针,slice,和map的零值都是nil,即还没有分配
1 | package main |
输出:1
2
3
4
5{ 0 [0 0 0 0 0] <nil> [] map[]}
ok1
ok2
ok3
{ 0 [0 0 0 0 0] <nil> [100 0 0 0 0 0 0 0 0 0] map[key1:tom]}
- 不同结构体变量的字段是独立,互不影响,
一个结构体变量字段的更改,不影响另外一个,结构体是值类型
1 | package main |
输出:1
2monster_one= {牛 123}
monster_two= {猴 143}
- 创建结构体变量和访问结构体字段
方式1-直接声明var person Person
方式2-{} var person Person = Person{}
方式3-& varperson*Person=new(Person)
方式4-{} var person *Person = &Person{}
说明:
- 第3种和第4种方式返回的是结构体指针
- 结构体指针访问字段的标准方式应该是:
(*结构体指针).字段名
,比如(*person).Name = "tom"
- go做了一个简化,也支持
结构体指针
.字段名,比如person.Name="tom"
。 - 这更加符合程序员使用的习惯,go编译器底层对
person.Name
做了转(*person).Name。
- struct类型的内存分配机制
1 | package main |
1 | 10 |
内存图:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26package main
import "fmt"
type Person struct {
Name string
Age int
}
func main() {
var p1 Person
p1.Age = 10
p1.Name = "小明"
var p2 *Person = &p1
fmt.Println((*p2).Age)
fmt.Println(p2.Age)
p2.Name = "小红"
fmt.Printf("p2.Name=%v p1.Name=%v \n", p2.Name, p1.Name)
fmt.Printf("p2.Name=%v p1.Name=%v \n", (*p2).Name, p1.Name)
fmt.Printf("p1的地址%p\n", &p1)
fmt.Printf("p2的地址%p p2的值%p", &p2,p2)
}
输出:1
2
3
4
5
610
10
p2.Name=小红 p1.Name=小红
p2.Name=小红 p1.Name=小红
p1的地址0xc0000044c0
p2的地址0xc000006028 p2的值0xc0000044c0
内存图: