Go语言基础
介绍
基础
介绍
- 本文介绍Go语言中面向对象(封装、继承、多态)相关特性、反射(Type、Value、动态创建结构体)相关特性、等相关知识。
基础
面向对象
- Go语言是否是一门面向对象的语言,Golang 官方答案是:YES OR NO。
- Go语言从设计和语法上本身是一门面向过程、支持并发的语言,没有类、继承和多态的特性。
- Go语言提供了部分面向对象的特性、可以实现类似面向对象程序设计。
封装
- 封装就是隐藏实现细节,将数据和方法使用语法规则约束(类似private),外部对象无法直接访问数据字段,只能通过所提供的方法进行操作。在面向对象语言中,封装是类 class 提供的特性。
- Go语言没有类的概念,但提供了结构体的定义,可以将属性字段定义在结构体中,通过实例化结构体对象来访问字段。结构体中不能定义方法,都在类外定义。
- Go语言中,通过变量名或方法名首字母的大小写来实现类似public和private功能,但在同一个包中,不管首大写或小写都在包内可见,所以在Go语言中,对封装的约束是在包级别的约束,同一个包内无访问限制。
// 包 pkgtest 内容,文件名称 pkgtest.go
package pkgtest
import "fmt"
// 结构体及所有字段外部可直接访问
type NetAddr struct {
Ip string
Port int
}
// 结构体外部可直接访问,字段外部不可访问
type NetAddrs struct {
ip string
port int
}
// 提供外部直接访问的方法
func (c *NetAddrs) SetAddrPort(ip string, port int) {
c.ip = ip
c.port = port
}
// 自定义结构体打印信息
func (c *NetAddrs) String() string {
return fmt.Sprintf("ip: %#v, port: %#v", c.ip, c.port)
}
// main 包 main.go 文件
package main
import (
"fmt"
"pkgtest"
)
func main() {
a := pkgtest.NetAddr{"127.0.0.1", 9080}
fmt.Printf("a = ip: %#v, port: %#v\n", a.Ip, a.Port)
var b pkgtest.NetAddrs
fmt.Println("b = ", &b)
b.SetAddrPort("127.0.0.1", 9090)
fmt.Println("b = ", &b)
}
输出结果
a = ip: “127.0.0.1”, port: 9080
b = ip: “”, port: 0
b = ip: “127.0.0.1”, port: 9090
继承
- 继承可以提高程序代码复用性,将多个结构体所存在的相同的属性字段和方法提取出来,抽象出一个新的结构体作为基类,其它派生类去继承此类的特性,并且可以扩展自有属性和方法。
- Go语言中没有继承的概念,通过匿名结构体嵌套来实现继承的效果,与真正的继承存在一些区别。
- Go语言支持多继承,即在结构体中嵌套多个匿名结构体。
- 通过嵌入结构体类型实现代码复用和扩展性并不是完全等同于传统面向对象语言中的继承关系。
package main
import "fmt"
type Animal struct {
name string
}
// 基类方法
func (c Animal) GetName() string {
return fmt.Sprintf("name: %#v", c.name)
}
type Cat struct {
Animal // 继承Animal
id int
}
// 派生类独有方法
func (c Cat) Voice() {
fmt.Println("id: ", c.id, ", cat ~~~~~~")
}
func main() {
ani := Animal{"animal"}
fmt.Println(ani, ", ", ani.GetName())
cat := &Cat{Animal{"maomao"}, 10010}
fmt.Println(cat)
fmt.Println(cat.GetName())
cat.Voice()
}
输出结果
{animal} , name: “animal”
&{ {maomao} 10010}
name: “maomao”
id: 10010 , cat ~~~~~~
- 重写基类方法。
package main
import "fmt"
type Animal struct {
name string
}
// 基类方法
func (c Animal) GetName() string {
return fmt.Sprintf("Animal name: %#v", c.name)
}
type Cat struct {
Animal // 继承Animal
}
// 派生类重新基类方法
func (c Cat) GetName() string {
return fmt.Sprintf("Cat name: %#v", c.name)
}
func main() {
ani := Animal{"animal"}
fmt.Println(ani, ", ", ani.GetName())
cat := Cat{Animal{"cat"}}
fmt.Println(cat, ", ", cat.GetName())
}
输出结果
{animal} , Animal name: “animal”
{ {cat}} , Cat name: “cat”
多态
- 多态是指一个对