面向对象的引入
- 很多人说Go是面向对象的语言,Golang确实支持OOP,但是和传统的面向对象编程有区别,并不是纯粹的面向对象语言。所以我们说Golang支持面向对象编程特性是比较准确的。
- Golang没有类(class),Go语言的结构体(struct)和其它编程语言的类(class)有同等的地位,你可以理解Gelang是基于struct来实现OOP特性的
- Golang面向对象编程非常简洁,去掉了传统OOP语言的方法重载、构造函数和析构函数、隐藏的this指针等等
- Golang仍然有面向对象编程的继承,封装和多态的特性,只是实现的方式和其它OOP语言不一样,比如继承:Golang没有extends 关键字,继承是通过匿名字段来实现。
结构体的定义
有点Java基础的,下面的定义方式一看就懂了
type Teacher struct {
// 变量名大写外界可以访问这个属性
Name string
Age int
School string
}
func main (){
// 创建老师结构体的实例
var t1 Teacher // 这和定义变量是一样的(var a int)
fmt.Println(t1) // 在未赋值时默认是{ 0 }
t1.Name = "赫敏·格兰杰"
t1.Age = 15
t1.School = "霍格沃兹"
fmt.Println(t1)
}
结构体创建实例的4种方式
上述代码就是第一种创建方式,下面展示其它三种基本创建方式
type Teacher struct {
Name string
Age int
School string
}
func main (){
var t1 Teacher = Teacher{"赫敏·格兰杰",15,"霍格沃兹"}
fmt.Println(t1)
}
第三种方式创建后实际上返回的是结构体的指针:
func main(){
var t *Teacher = new(Teacher)
// 这里t就是指向Teacher对象的地址,要想给Teacher实例的字段赋值,就要对地址t取值
(*t).Name = "哈利"
(*t).Age = 15
fmt.Println(*t)
}
但是上面这种方式看起来有些麻烦,为了符合程序员的习惯,go提供了简化的赋值方式,如下:
func main(){
var t *Teacher = new(Teacher)
t.Name = "哈利" // Go的编译器底层帮你实现了上面的转化过程
t.Age = 15
fmt.Println(*t)
}
接下来看方式四,返回的同样是结构体的指针
func main(){
var t *Teacher = &Teacher{"哈利",15}
fmt.Println(*t)
}
这就是指针部分的基础内容,&是对变量取地址,*和 & 可以互相抵消。
结构体之间的转换
结构体是用户单独定义的类型,和其他类型进行转换时需要具有完全相同的字段(名字、个数、类型)
package main
import "fmt"
type Student struct {
Age int
}
type Person struct {
Age int
}
func main (){
var s Student = Student{10}
var p Person = Person{15}
s = Student{p} // 主要需要使用规定的强制转换,s = p是不行的
fmt.Println(s)
fmt.Println(p)
}
程序输出
{15}
{15}
注意: 如果我们对同一个结构体进行重新定义(相当于取别名),例如:type Stu Student,尽管他们是一个东西,GoLang会认为这是新的数据类型,二者之间仍然需要强制的转换。