一、OOP特性
Go语言中的OOP特性
- 结构体:在Go中,结构体用于定义复合类型,类似于其他语言中的类。它可以包含字段(属性)和方法(行为)。
- 方法:Go允许为任何自定义类型(包括结构体)定义方法,这与传统OOP语言中类的方法类似。
- 接口:接口是方法的集合,实现了这些方法的类型即实现了该接口。Go的接口提供了一种灵活的方式来进行多态操作
- 组合而非继承:Go提倡使用组合而非继承来重用代码。你可以将一个结构体嵌入到另一个结构体中,以达到类似继承的效果
二、普通版本OOP
package mainimport "fmt"//定义文件操作者接口
type FileOperator interface {read()write()
}//定义文件结构体
type File struct {path stringsize intlabel string
}//定义XMLFile结构体,继承File结构体
type XMLFile struct {Fileowner string
}// 定义File结构体的方法read
func (file File) read() {fmt.Println(file.label, "读取文件")
}// 定义File结构体的方法write
func (file File) write() {fmt.Println(file.label, "写入文件")
}// 定义函数useInterface,函数与方法的区别:函数不需要接收者,
// 方法需要接收者,上面read和write方法的接收者是File结构体的实例
// 该函数参数为实现了FileOperator接口的实例
func useInterface(fileOperator FileOperator) {fileOperator.read()fileOperator.write()
}// 重写父结构体write方法
func (xml XMLFile) write() {fmt.Println(xml.label, "重写父结构体write方法,写入文件")
}func main() {// 实例化File结构体commonlFile := File{path: "/root",size: 3000,label: "普通文件",}// 调用接口函数,commonlFile实现了接口的所有方法,所以能够作为参数传入useInterface(commonlFile)// 实例化xmlFile结构体,并实例化父结构体,File也可以直接用上面的父实例commonlFile,如下:// xmlFile := XML{// owner: "root",// File: commonlFile// }xmlFile := XMLFile{owner: "root",File: File{path: "/home",size: 1000,label: "xml文件",},}// 调用接口函数,传入子结构体实例,子结构体重写了write方法useInterface(xmlFile)
}
输出
普通文件 读取文件
普通文件 写入文件
xml文件 读取文件
xml文件 重写父结构体write方法,写入文件
三、带指针的OOP
指针的好处:
1. 性能优化
减少内存拷贝:当你将一个大结构体或数组传递给函数时,如果不使用指针而是直接传递值,则会创建该数据的一个副本。对于大型数据结构,这可能导致显著的性能开销。通过使用指针,你可以避免这种不必要的复制,从而提高性能。
2. 修改原值的能力
改变调用者的数据:当函数参数是指针时,函数内部对参数所做的任何更改都会反映在调用者的数据上。这是因为函数接收的是实际数据的地址而不是其副本。这对于需要返回多个结果或者需要修改外部状态的函数非常有用。
3. 高效的结构体操作
在处理结构体时,如果结构体较大,使用指针可以避免大量的内存复制。此外,在并发编程中,通过指针共享数据结构是常见做法,尽管需要注意同步问题以避免竞态条件。
4. 动态分配内存
使用new()或make()等内置函数动态分配内存,并通过指针访问这块内存,可以使你的程序更加灵活。例如,当你不知道程序运行时需要多少元素的切片或映射时,可以通过指针来管理动态增长的数据结构。
package mainimport "fmt"//定义文件操作者接口
type FileOperator interface {read()write()
}//定义文件结构体
type File struct {path stringsize intlabel string
}//定义XMLFile结构体,继承File结构体
type XMLFile struct {*Fileowner string
}// 定义File结构体的方法read
func (file *File) read() {fmt.Println(file.label, file.path, "读取文件")
}// 定义File结构体的方法write
func (file *File) write() {fmt.Println(file.label, file.path, "写入文件")
}// 定义修改文件路径方法
func (file *File) modifyPath(newPath string) {file.path = newPath
}// 定义函数useInterface,函数与方法的区别:函数不需要接收者,
// 方法需要接收者,上面read和write方法的接收者是File结构体的实例
// 该函数参数为实现了FileOperator接口的实例
func useInterface(fileOperator FileOperator) {fileOperator.read()fileOperator.write()
}// 重写父结构体write方法
func (xml *XMLFile) write() {fmt.Println(xml.label, "重写父结构体write方法,写入文件")
}func main() {// 实例化File结构体commonlFile := File{path: "/root",size: 3000,label: "普通文件",}// 调用接口函数,commonlFile实现了接口的所有方法,所以能够作为参数传入useInterface(&commonlFile)// 实例化xmlFile结构体,并实例化父结构体,File也可以直接用上面的父实例commonlFile,如下:// xmlFile := XML{// owner: "root",// File: &commonlFile// }xmlFile := &XMLFile{owner: "root",File: &File{path: "/home",size: 1000,label: "xml文件",},}xmlFile.modifyPath("/root/xml")// 调用接口函数,传入子结构体实例,子结构体重写了write方法useInterface(xmlFile)
}
输出
普通文件 /root 读取文件
普通文件 /root 写入文件
xml文件 /root/xml 读取文件
xml文件 重写父结构体write方法,写入文件