createdtime 20211013
updatedtime 20211013
author Venki
- golang中没有构造函数,通常可以通过工厂模式解决这个问题。
- 定义一个小写字母开头的结构体,相当于私有的,其他包无法使用,如果其他包想要使用,那么可以借助工厂模式解决。
type student struct {
Name string
Age int
}
func NewObject(n string, a int) *student {
return &student{
Name: n,
Age: a,
}
}
-
面向对象之封装性:①结构体,属性首字母小写;②提供一个工厂函数;③提供一个
Set
方法;④提供一个Get
方法。 -
面向对象之继承性:解决代码冗余。匿名结构体实现继承。如果一个结构体嵌套了另一个匿名结构体,那么这个结构体可以直接访问匿名结构体的字段和方法。如果一个结构体继承另一个结构体之后,可以直接用这个结构体的实例调用另一个结构体中的属性和方法,因为编译器会按照一定的顺序进行寻找对应的字段和方法。
-
结构体嵌入两个(或多个)匿名结构体,如果两个匿名结构体有相同的字段和方法(同时结构体本身没有同名的字段和方法),在访问时,就必须明确指定匿名结构体名字,否则编译报错。
-
如果一个struct嵌套了一个有名结构体,这种模式就是组合,如果是组合关系,那么在访问组合的结构体的字段或者方法时,必须带上结构体的名字。
-
建议尽量不要使用多重继承。
-
接口(interface):接口只需要定义方法,不用实现,并且interface不能包含任何变量。
-
golang语言没有implement关键字。
-
接口注意事项:
- 接口本身不能创建实例,但是可以指向一个实现了该接口的自定义类型的变量(实例)。
- 在golang中,一个自定义类型必须实现接口中的全部方法。
- 只要是自定义数据类型,都可以实现接口中的所有方法。
- 一个自定义类型可以实现多个接口。
- 接口中不能有任何变量。
- 一个接口(比如A接口)可以继承多个别的接口(比如B/C接口),这时如果实现A接口,也必须将B、C接口的方法全部实现。
- interface类型默认是一个指针(引用类型),如果没有对interface初始化就使用,那么会输出nil。
- 空接口没有任何方法,所以所有类型都实现了空接口。
- 两个接口同时被第三个接口使用时,接口中的方法名不能重复。
-
引用类型的使用,必须要进行实例,不然报nil空指针。
-
指针类型的结构体和结构体是不同的数据类型,所以接口中方法的实现,一定要注意实现接口方法的数据类型(到底是指针类型的结构体(*stu)还是结构体(stu))。
-
接口是对继承的一种补充。继承结构体的同时不想破坏结构体的组织形式,那么可以通过接口进行扩展。
-
继承的价值主要在于:解决代码的复用性和可维护性。
-
接口的价值主要在于:设计,设计好各种规范(方法),让其它自定义类型去实现这些方法。
func Access() {
interfaceStudy()
}
// 接口练习
/*定义一个自定义切片类型,用来存储结构体,然后按照结构体中指定字段进行排序*/
func interfaceStudy() {
var heroes Heroes
var age int = 20
for i := 0; i < 10; i++ {
index := rand.Intn(100)
hero := Hero{
Name: fmt.Sprintf("英雄-%d", i+1),
Age: age + index,
}
heroes = append(heroes, hero)
}
// 排序前的顺序
for _, value := range heroes {
fmt.Println(value)
}
fmt.Println("----------------------")
sort.Sort(heroes)
// 排序后的顺序
for _, value := range heroes {
fmt.Println(value)
}
}
// Hero 定义一个结构体
type Hero struct {
Name string
Age int
}
// Heroes 声明一个结构体类型切片
type Heroes []Hero
// Len 如果想用sort包中的sort方法,那么必须实现其方法
// Heroes本身就是引用类型,不需要*Heroes
func (hero Heroes) Len() int {
return len(hero)
}
func (hero Heroes) Less(i, j int) bool {
return hero[i].Age < hero[j].Age // 升序
// return hero[i].Age > hero[j].Age // 降序
}
// Swap Less()返回后的结果为真,则调用Swap()进行交互
func (hero Heroes) Swap(i, j int) {
hero[i], hero[j] = hero[j], hero[i]
}
- 接口比继承更加灵活,接口实现是基于方法的,不需要显性绑定接口,从而松耦合。
- 变量(实例)具有多种形态。在go语言中,多态特征是通过接口实现的。可以按照统一的接口来调用不同的实现。这时接口变量就呈现不同的形态。
- 多态参数和多态数据。
- 类型断言:在进行类型断言时,要确保类型匹配。
- 类型断言,由于接口是一般类型,不知道具体类型,如果要转成具体类型,就需要使用类型断言。