面向对象编程(一):类的定义、初始化和成员方法
1 类的定义和初始化
Go 语言的面向对象编程没有 class
、 extends
、implements
之类的关键字和相应的概念,而是借助结构体来实现类的声明,如下是定义一个学生类的方法:
type Student struct{
id uint
name string
male bool
score float64
}
类名为 Student
,并且包含了 id
、name
、male
、score
这四个属性。
相应的,Go 语言中也不支持构造函数、析构函数,需要我们自定义形如 Newxxx
这样的全局函数(首字母大写)作为类的初始化函数方法:
// 初始化方法(全量定义)
func NewStudent(id uint, name string, male bool, score float64) *Student {
return &Student{id, name, male, score}
}
在如上函数中,通过传入 NewStudent
方法的字段对 Student
类进行初始化,并返回一个指向该类的指针。此外,还能够初始化指定字段,如下所示:
// 初始化方法(部分定义)
func NewStudentPart(id uint, name string, score float64) *Student {
return &Student{id: id, name: name, score: score}
}
在 main
方法中调用初始化的方法,打印如下:
// 类的初始化
student := GoClass.NewStudent(1, "南歌", false, 100)
fmt.Println(student)
// male未定义,会默认为male的零值false
student2 := GoClass.NewStudentPart(1, "南歌", 100)
fmt.Println(student2)
2 成员方法
同上所述,Go 语言中的成员方法也需要编写函数方法来实现,主要有 值方法 和 指针方法,两种方法的使用分别如下:
值方法
func (s Student) GetName() string {
return s.name
}
通过定义的 GetName()
方法,就可以在初始化 Student
类后,调用 GetName()
成员方法,使用如下:
student := GoClass.NewStudent(1, "南歌", false, 100)
fmt.Println("Name:", student.GetName())
注意:我们通过在函数签名中增加接收者声明的方式定义了函数所归属的类型,这个时候,函数就不再是普通的函数,而是类的成员方法了。
指针方法
上面的 值方法 只能够进行函数属性的读取,而不能做修改,可以使用如下方法简单进行测试。
func (s Student) SetName(name string) {
fmt.Println(s)
s.name = name
fmt.Println(s)
}
在 main
函数中调用 SetName
方法,如下所示:
student3 := GoClass.NewStudent(1, "南歌", false, 100)
fmt.Println("Name:", student3.GetName())
student3.SetName("euansu")
fmt.Println("Name:", student3.GetName())
如上所示,在调用 SetName()
的时候,Student
并未接收函数的返回,因此即使修改了 s.name
,但是类 Student
的属性也未被修改,如果要修改类 Student
的属性,就需要通过指针方法对其进行修改,如下所示:
func (s *Student) SetName(name string) {
s.name = name
}
在 main
函数中按照如下方法进行调用。
student4 := GoClass.NewStudent(1, "南歌", false, 100)
fmt.Println("Name:", student4.GetName())
student4.SetName("euansu")
fmt.Println("Name:", student4.GetName()
3 总结
- Go 语言与其他编程语言相比,弱化了类的概念,而是使用结构体定义类,类内部的数据类型与普通的数据类型一样,内置的数据类型也可以通过关键字指定为包含自定义成员方法的类。
- Go 语言中,类的成员方法有两种,分别是值方法和指针方法,其中值方法主要是用做读取类成员属性的场景,而指针方法则是用作修改类成员属性的场景。