我是小小搬运工,本文章仅作为自己的学习笔记,后续还会进行知识点补充。
推荐大家去看原链接学习:传送门 ===》煎鱼大佬
在了解 Go 语言是不是面向对象(简称:OOP) 之前,我们必须先知道 OOP 是啥,得先给他 “下定义”
根据 Wikipedia 的定义,我们梳理出 OOP 的几个基本认知:
基于这几个基本认知进行一步延伸出,面向对象的三大基本特性:
“Go 语言是否一门面向对象的语言?”,这是一个日经话题。官方 FAQ 给出的答复是:
是的,也不是。原因是:
面向对象中的 “封装” 指的是可以隐藏对象的内部属性和实现细节,仅对外提供公开接口调用,这样子用户就不需要关注你内部是怎么实现的。
在 Go 语言中的属性访问权限,通过首字母大小写来控制:
Go 语言的例子如下:
type Animal struct {
name string
}
func NewAnimal() *Animal {
return &Animal{}
}
func (p *Animal) SetName(name string) {
p.name = name
}
func (p *Animal) GetName() string {
return p.name
}
在上述例子中,我们声明了一个结构体 Animal
,其属性 name
为小写。没法通过外部方法,在配套上存在 Setter 和 Getter 的方法,用于统一的访问和设置控制。
以此实现在 Go 语言中的基本封装。
面向对象中的 “继承” 指的是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
从实际的例子来看,就是动物是一个大父类,下面又能细分为 “食草动物”、“食肉动物”,这两者会包含 “动物” 这个父类的基本定义。
在 Go 语言中,是没有类似 extends
关键字的这种继承的方式,在语言设计上采取的是组合的方式:
type Animal struct {
Name string
}
type Cat struct {
Animal
FeatureA string
}
type Dog struct {
Animal
FeatureB string
}
在上述例子中,我们声明了 Cat
和 Dog
结构体,其在内部匿名组合了 Animal
结构体。因此 Cat
和 Dog
的实例都可以调用 Animal
结构体的方法:
func main() {
p := NewAnimal()
p.SetName("我是搬运工,去给煎鱼点赞~")
dog := Dog{Animal: *p}
fmt.Println(dog.GetName())
}
同时 Cat
和 Dog
的实例可以拥有自己的方法:
func (dog *Dog) HelloWorld() {
fmt.Println("脑子进煎鱼了")
}
func (cat *Cat) HelloWorld() {
fmt.Println("煎鱼进脑子了")
}
上述例子能够正常包含调用 Animal
的相关属性和方法,也能够拥有自己的独立属性和方法,在 Go 语言中达到了类似继承的效果。
面向对象中的 “多态” 指的同一个行为具有多种不同表现形式或形态的能力,具体是指一个类实例(对象)的相同方法在不同情形有不同表现形式。
多态也使得不同内部结构的对象可以共享相同的外部接口,也就是都是一套外部模板,内部实际是什么,只要符合规格就可以。
在 Go 语言中,多态是通过接口来实现的:
type AnimalSounder interface {
MakeDNA()
}
func MakeSomeDNA(animalSounder AnimalSounder) { // 参数是AnimalSounder接口类型
animalSounder.MakeDNA()
}
在上述例子中,我们声明了一个接口类型 AnimalSounder
,配套一个 MakeSomeDNA
方法,其接受 AnimalSounder
接口类型作为入参。
因此在 Go 语言中。只要配套的 Cat
和 Dog
的实例也实现了 MakeSomeDNA
方法,那么我们就可以认为他是 AnimalSounder
接口类型:
type AnimalSounder interface {
MakeDNA()
}
func MakeSomeDNA(animalSounder AnimalSounder) {
animalSounder.MakeDNA()
}
func (c *Cat) MakeDNA() {
fmt.Println("煎鱼是煎鱼")
}
func (c *Dog) MakeDNA() {
fmt.Println("煎鱼其实不是煎鱼")
}
func main() {
MakeSomeDNA(&Cat{})
MakeSomeDNA(&Dog{})
}
当 Cat
和 Dog
的实例实现了 AnimalSounder
接口类型的约束后,就意味着满足了条件,他们在 Go 语言中就是一个东西。能够作为入参传入 MakeSomeDNA
方法中,再根据不同的实例实现多态行为。
在日常工作中,基本了解这些概念就可以了。若是面试,可以针对三大特性:“封装、继承、多态” 和 五大原则 “单一职责原则(SRP)、开放封闭原则(OCP)、里氏替换原则(LSP)、依赖倒置原则(DIP)、接口隔离原则(ISP)” 进行深入理解和说明。
在说明后针对上述提到的概念。再在 Go 语言中讲解其具体的实现和利用到的基本原理,互相结合讲解,就能得到一个不错的效果了。