大家好,我是煎鱼。
在大家初识 Go 语言时,总会拿其余语言的根本个性来类比 Go 语言,说白了就是老常识和新常识产生关联,实现更高的学习效率。
最常见的类比,就是“Go 语言如何实现面向对象?”,进一步开展就是 Go 语言如何实现面向对象个性中的继承。
这不仅在学习中才用到类比,在业内的 Go 面试中也有十分多的面试官喜爱问:
来自读者微信群
在明天这篇文章中,煎鱼带大家具体开展理解这块的常识。一起欢快地开始吸鱼之路。
什么是面向对象
在理解 Go 语言是不是面向对象(简称:OOP)之前,咱们必须先晓得 OOP 是啥,得先给他“下定义”。
依据 Wikipedia 的定义,咱们梳理出 OOP 的几个根本认知:
- 面向对象编程(OOP)是一种基于 “ 对象 ” 概念的编程范式,它能够蕴含数据和代码:数据以字段的模式存在(通常称为属性或属性),代码以程序的模式存在(通常称为办法)。
- 对象本人的程序能够拜访并常常批改本人的数据字段。
- 对象常常被定义为类的一个实例。
- 对象利用属性和办法的公有 / 受爱护 / 公共可见性,对象的外部状态受到爱护,不受外界影响(被封装)。
基于这几个根本认知进行一步延长出,面向对象的三大根本个性:
- 封装。
- 继承。
- 多态。
至此对面向对象的基本概念解说完结,想更进一步理解的可自行网上冲浪。
Go 是面向对象的语言吗
“Go 语言是否一门面向对象的语言?”,这是一个日经话题。官网 FAQ 给出的回答是:
是的,也不是。起因是:
- Go 有类型和办法,并且容许面向对象的编程格调,但没有类型档次。
- Go 中的 “ 接口 “ 概念提供了一种不同的办法,咱们认为这种办法易于应用,而且在某些方面更加通用。还有一些办法能够将类型嵌入到其余类型中,以提供相似的货色,但不等同于子类。
- Go 中的办法比 C++ 或 Java 中的办法更通用:它们能够为任何类型的数据定义,甚至是内置类型,如一般的、” 未装箱的 “ 整数。它们并不局限于构造(类)。
- Go 因为不足类型档次,Go 中的 “ 对象 “ 比 C++ 或 Java 等语言更笨重。
Go 实现面向对象编程
封装
面向对象中的“封装”指的是能够暗藏对象的外部属性和实现细节,仅对外提供公开接口调用,这样子用户就不须要关注你外部是怎么实现的。
在 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.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
办法中,再依据不同的实例实现多态行为。
总结
通过明天这篇文章,咱们根本理解了面向对象的定义和 Go 官网对面向对象这一件事的认识,同时针对面向对象的三大个性:“封装、继承、多态”在 Go 语言中的实现办法就进行了一一解说。
在日常工作中,根本理解这些概念就能够了。若是面试,能够针对三大个性:“封装、继承、多态”和 五大准则“繁多职责准则(SRP)、凋谢关闭准则(OCP)、里氏替换准则(LSP)、依赖倒置准则(DIP)、接口隔离准则(ISP)”进行深刻了解和阐明。
在阐明后针对上述提到的概念。再在 Go 语言中解说其具体的实现和利用到的基本原理,相互联合解说,就能失去一个不错的成果了。
若有任何疑难欢送评论区反馈和交换,最好的关系是相互成就 ,各位的 点赞 就是煎鱼创作的最大能源,感激反对。
文章继续更新,能够微信搜【脑子进煎鱼了】浏览,本文 GitHub github.com/eddycjy/blog 已收录,欢送 Star 催更。
参考
- Is Go an Object Oriented language?
- 面向对象的三大基本特征,五大根本准则
- Go 面向对象编程(译)