【golang面经】面向对象
什么是面向对象?
面向对象简称OOP,具有封装 继承 多态 三大特性
golang的面向对象
封装
面向对象中的封装是指将对象内部的属性隐藏,开放公开的方法或接口用实现修改,查询等操作
go中的权限是由常量,变量,结构体,函数,属性等首字母是否大写来控制是否可被外部访问
- 首字母大写代表公开,可以被外部访问
- 首字母小写代表私有,不可被外部访问
示例:
示例结构如下
- oop
- model
model.go
main.go
其中model.go
内容如下
package model
type Person struct {
name string
}
main.go
如下
package main
import (
"fmt"
"oop/model"
)
func main() {
person := new(model.Person)
fmt.Println(person)
}
-
在结构体名首字母大写,结构体属性首字母小写的情况下
可以创建实例,无法操作属性
可以在
model.go
中编写 setter 与 getter 方法来操作属性// model.go package model type Person struct { name string } func (p *Person) SetName(name string) { p.name = name } func (p *Person) GetName() string { return p.name } // main.go package main import ( "fmt" "oop/model" ) func main() { person := new(model.Person) person.SetName("panda") fmt.Println(person.GetName()) fmt.Println(person) } // 运行结果为: // panda // &{panda}
-
在结构体名首字母小写,结构体属性首字母小写的情况下
无法创建结构体实例
可以在
model.go
中编写New方法来创建person
实例// model.go package model type person struct { name string } func NewPerson() *person { return &person{} } func (p *person) SetName(name string) { p.name = name } func (p *person) GetName() string { return p.name } // main.go package main import ( "fmt" "oop/model" ) func main() { person := model.NewPerson() person.SetName("panda") fmt.Println(person.GetName()) fmt.Println(person) } // 运行结果为: // panda // &{panda}
-
结构体首字母大写不展示
继承
面向对象的继承是指子类继承父类的属性与方法,使子类具有父类相同的属性行为
在go中的继承是通过组合实现的,
示例:
// model.go
package model
type Person struct {
name string
}
type Man struct {
Person
}
type Woman struct {
Person
}
func NewPerson() *Person {
return &Person{}
}
func (p *Person) SetName(name string) {
p.name = name
}
func (p *Person) GetName() string {
return p.name
}
// main.go
package main
import (
"fmt"
"oop/model"
)
func main() {
person := model.NewPerson()
person.SetName("panda")
fmt.Println(person.GetName())
fmt.Println(person)
}
// 运行结果为:
// panda
// &{panda}
// man
// {{man}}
多态
面向对象中的多态是指同一个行为具有不同的实现方式,但在某种意义来说是属于同一种行为
golang中的多态是通过接口实现的,接口中定义了某些方法,若某些结构体实现了这个接口所有的方法,那么就认为这个结构体是定义的接口类型
举例:
person有man和woman,他们都是worker,每天都要上班下班,man工作时间为朝九晚六,woman工作时间为朝十晚七
示例:
在下面的例子中增加了Worker的接口,声明了两个方法,在Person结构体实现了这两个方法,并且配置了所有属性的getter & setter,Man与Woman通过匿名组合的方式继承了person的属性以及方法
在main.go
中编写了CallWork
的方法,并传入操作的类型,与具体的worker,由于Man与Woman继承了person的方法,所以也实现了Worker接口,这样就通过多态的形式实现了调用
// model.go
package model
import "fmt"
type Person struct {
doWorkTime string
downWorkTime string
name string
}
type Worker interface {
DoWork()
DownWork()
}
type Man struct {
Person
}
type Woman struct {
Person
}
func NewPerson() *Person {
return &Person{}
}
func (p *Person) GetDoWorkTime() string {
return p.doWorkTime
}
func (p *Person) SetDoWorkTime(doWorkTime string) {
p.doWorkTime = doWorkTime
}
func (p *Person) GetDownWorkTime() string {
return p.downWorkTime
}
func (p *Person) SetDownWorkTime(downWorkTime string) {
p.downWorkTime = downWorkTime
}
func (p *Person) SetName(name string) {
p.name = name
}
func (p *Person) GetName() string {
return p.name
}
func (p *Person) DoWork() {
fmt.Printf("%s %s 开始上班\n", p.name, p.GetDoWorkTime())
}
func (p *Person) DownWork() {
fmt.Printf("%s %s 开始下班\n", p.name, p.GetDownWorkTime())
}
// main.go
package main
import (
"oop/model"
)
type workType int
const (
doWork workType = iota
downWork
)
func CallWork(t workType, worker ...model.Worker) {
switch t {
case downWork:
for _, wk := range worker {
wk.DownWork()
}
case doWork:
for _, wk := range worker {
wk.DoWork()
}
}
}
func main() {
man := model.Man{}
woman := model.Woman{}
man.SetName("man")
man.SetDoWorkTime("九点")
man.SetDownWorkTime("六点")
woman.SetName("woman")
woman.SetDoWorkTime("十点")
woman.SetDownWorkTime("七点")
CallWork(doWork, &man, &woman)
CallWork(downWork, &man, &woman)
}
// 运行结果为:
// man 九点 开始上班
// woman 十点 开始上班
// man 六点 开始下班
// woman 七点 开始下班
评论区