结构体
Goland语言面向对象编程说明
1,Goland 也支持面向对象编程(OOP)但是和传统的面向对象编程有区别 并不是纯粹的面向对象语言 所以说Goland 支持面向对象编程的特性是比较准确的
2, Goland 没有类(class)Go 语言的结构体(struct)和其他编程语言的类(class)有同等地位 可以理解Goland 是基于struct 来实现OOP特性的
3,Goland 面向对象编程非常简洁 去掉了传统OOP 语言的继承 方法重载 构造函数和析构函数 隐藏的this 指针等等
4, Golang仍然有面向对象编程的继承,封装和多态的特性,只是实现的方式和其它OOP语言不一样,比如继承:Golang没有extends关键字,继承是通过匿名字段来实现。
5, Golang面向对象(OOP)很优雅,OOP本身就是语言类型系统(type system)的一部分,通过接口(interface)关联,耦合性低,也非常灵活。后面同学们会充分体会到这个特点。也就是说在Golang中面向接口编程是非常重要的特性。
快速入门案例
结构体和结构体变量(实例)的区别和联系
通过上面的案例可以看出:
1)结构体是自定义的数据类型,代表一类事物.
2)结构体变量(实例是具体的,实际的,代表一个具体变量
结构体的字段介绍
1)从概念或叫法上看:结构体字段=属性=field(即授课中,统一叫字段)
2)字段是结构体的一个组成部分,一般是基本数据类型、数组,也可是引用类型。比如我们前面定义猫结构体的 Name string就是属性
取值的方式
方法
基本介绍
在某些情况下,我们要需要声明(定义)方法。比如Person结构体:除了有一些字段外(年龄,姓名…)Person结构体还有一些行为比如:可以说话、跑步.,通过学习,还可以做算术题。这时就要用方法才能完成。
Golang中的方法是作用在指定的数据类型上的(即:和指定的数据类型绑定),因此自定义类型,都可以有方法,T而不仅仅是struct
入门案例
方法的声明(定义)
fund (recevier type) methodName(参数列表)(返回值列表){
方法体
return返回值
}
1)参数列表:表示方法输入
2) recevier type:表示这个方法和type这个类型进行绑定,或者说该方法作用于type类型3) receiver type : type可以是结构体,也可以其它的自定义类型
4)receiver :就是type类型的一个变量(实例),比如:Person结构体的一个变量(实例)5)参数列表:表示方法输入
6)返回值列表:表示返回的值,可以多个7)方法主体:表示为了实现某一功能代码块)return语句不是必须的。
方法注意事项和细节讨论
1))结构体类型是值类型,在方法调用中,遵守值类型的传递机制,是值拷贝传递方式
2)如程序员希望在方法中,修改结构体变量的值,可以通过结构体指针的方式来处理
3) Golang中的方法作用在指定的数据类型上的(即:和指定的数据类型绑定),
因此自定义类型,都可以有方法,而不仅仅是strupt,比如int , float32等都可以有方法
4)方法的访问范围控制的规则,和函数一样。方法名首字母小写,只能在本包访问,方法首字母大写,可以在本包和其它包访问。[讲解]
5)如果一个变量实现了String()这个方法,那么fmt.Println默认会调用这个变量的String()进行输出
方法和函数区别
1)调用方式不一样
函数的调用方式:
函数名(实参列表)
方法的调用方式:
变量.方法名(实参列表)
2)对于普通函数,接收者为值类型时,不能将指针类型的数据直接传递,反之亦然
3)对于方法(如struct的方法),接收者为值类型时,可以直接用指针类型的变量调用方法,反过来同样也可以
工厂模式
说明
Golang的结构体没有构造函数,通常可以使用工厂模式来解决这个问题。
看一个需求
一个结构体的声明是这样的:package model
type Student struct {Name string…
}
因为这里的student 的首字母s是大写的,如果我们想在其它包创建Student的实例(比如main包),引入model包后,就可以直接创建Student结构体的变量(实例)。但是问题来了,如果首字母是小写的,比如是type student struct {…}就不不行了,怎么办—>工厂模式来解决.
封装
封装介绍
封装(encapsulation)就是把抽象出的字段和对字段的操作封装在壬起,数据被保护在内部,程序的其它包只有通过被授权的操作(方法),才能对字段进行操作。
封装的理解和好处
1)隐藏实现细节
2)提可以对数据进行验证,保证安全合理(Age)
如何体现封装
1)对结构体中的属性进行封装
2)通过方法,包实现封装封装的实现步骤
1)将结构体、字段(属性)的首字母小写(不能导出了,其它包不能使用,类似private)2)给结构体所在包提供一个工厂模式的函数,首字母大写。类似一个构造函数
3)提供一个首字母大写的set方法(类似其它语言的public),用于对属性判断并赋值
func (var结构体类型名) SetXxx(参数列表)(返回值列表){
//加入数据验证的业务逻辑
var.字段=参数
4)提供一个首字母大写的Get方法(类似其它语言的public),用于获取属性的值
func (var结构体类型名)GetXxx() {
return var.age;
}
面向对象编程-继承继承基本介绍和示意图
继承可以解决代码复用,让我们的编程更加靠近人类思维。
当多个结构体存在相同的属性(字段)和方法时,可以从这些结构体中抽象出结构体(比如刚才的Studerlt),在该结构体中定义这些相同的属性和方法。
其它的结构体不需要重新定义这些属性和方法,只需嵌套一个student匿名结构体即可。[画出示意图]
也就是说:在Golang中,如果一个struct嵌套了另一个匿名结构体,那么这个结构体可以直接访问匿名结构体的字段和方法,从而实现了继承特性。
嵌套匿名结构体的基本用法
多重继承
多重继承说明
如一个struct嵌套了多个匿名结构体,那么该结构体可以直接访问嵌套的匿名结构体的字段和方法,从而实现了多重继承。
接口
入门案例
注意事项
1, 接口本身不能创建实例 但是可以指向一个实现改接口的自定义类型的变量(实例)
2,接口中所有的方法都没有方法体 即搜没有实现的方法
3,在Golang 中 一个自定义类型需要将某个接口的所有方法都实现 我们说这个自定义类型实现了该接口
4, 一个自定义类型只有实现了某个接口 才能将该自定义类型的实力(变量)赋给接口类型
5 只要是自定义数据类型就可以实现接口 不仅仅是结构体类型
接口跟继承的区别
1 当A 结构体继承B结构体 那么A结构就自动的继承了B结构体的字段和方法 并且可以直接使用
2, 当A 结构体需要扩展功能 同时不希望去破坏继承关系 则可以实现某个接口即可 因此我们可以认为:实现接口是对继承机制的补充
接口(interface)实现接口vs继承
1,接口和继承解决的解决的问题不同
继承的价值主要在于:解决代码的复用性和可维护性。
接口的价值主要在于:设计,设计好各种规范(方法),让其它自定义类型去实现这些方法。
2接口比继承更加灵活
接口比继承更加灵活,继承是满足is - a的关系,而接口只需满足 like - a的关系。
3 接口在一定程度上实现代码解耦
多态
基本介绍
变量(实例)具有多种形态。面向对象的第三大特征,在Go语言,多态特征是通过接口实现的。可以按照统一的接口来调用不同的实现。这时接口变量就呈现不同的形态。
快速入门
在前面的usb接口案例,Usb usb,既可以接收手机变量,又可以接收相机变量,就体现了usb接口多态特性。这个接口就体现了类的多种状态。 这个Usb 接口会根据传入的实参 来判断是IOS 还是安卓
接口体现多态的两种形式
1 多态参数
在前面的Usb接口案例,Usb usb ,即可以接收手机变量,又可以接收相机变量,就体现了Usb接口多态。
多态数组
演示一个案例:给Usb数组中,存放 Phone结构体和Camera结构体变量