posts - 177,comments - 14,views - 40万

面向对象定义

面向对象三要素:

  • 封装:将属性(数据)和方法(操作)封装,提供访问控制,隐藏实现细节,暴露该暴露的
  • 继承:子类可以从父类直接获得属性和方法,减少重复定义。子类中如果与父类不同,可以自己定 义新的属性和方法,也可以覆盖同名的属性和方法
  • 多态:前提是继承和覆盖,使得子类中虽然使用同一个方法,但是不同子类表现不同,就是不同的态

实现了以上特征的语言,才能成为面向对象编程范式语言。 严格意义来说,Go语言就是不想实现面向对象编程范式。但是面向对象又有一些不错的特性,Go语言 通过组合的方式实现了类似的功能。 只能说,Go语言实现了一种非常有自我特征的面向对象。

封装

通过结构体,可以把数据字段封装在内,还可以为结构体提供方法。

访问控制:

  • 属性、方法标识符首字母大写,实现了对包外可见的访问控制
  • 属性、方法标识符首字母小写,仅包内可见
  • 这些一定程度上实现了public、private的访问控制

构造函数

Go没有提供类似C++、Java一样的构造函数、析构函数。在Go中,用构造结构体实例的函数,这个函数 没有特别的要求,只要返回结构体实例或其指针即可(建议返回指针,不然返回值会拷贝)。习惯上, 构造函数命名是New或new开头。如果有多个构造函数,可以使用不同命名函数,因为Go也没有函数重载。通过不同的函数名来模拟构造函数重载。

复制代码
type Animal struct {
 name string
 age  int
}
func NewDefaultAnimal() *Animal {
 return &Animal{"nobody", 1}
}
func NewAnimal(name string, age int) *Animal {
 return &Animal{name, age}
}
复制代码

继承

Go语言没有提供继承的语法,实际上需要通过匿名结构体嵌入(组合)来实现类似效果。

复制代码
package main
import "fmt"
type Animal struct {
 name string
 age  int
}
func (*Animal) run() {
 fmt.Println("Animal run~~~")
}
type Cat struct {
 Animal // 匿名结构体嵌入
 color  string
}
func main() {
 cat := new(Cat)
 cat.run()
    cat.Animal.run()
}
复制代码

通过匿名结构体嵌入,子结构体就拥有了父结构体的属性name、age,和run方法。

覆盖

覆盖override,也称重写。不是重载overload。

// 为Cat增加一个run方法,这就是覆盖。
func (*Cat) run() {
 fmt.Println("Cat run+++")
}

上例增加run方法是完全覆盖,就是不依赖父结构体方法,重写功能。 如果是依赖父结构体方法,那就要在子结构体方法中显式调用它。

func (c *Cat) run() {
 c.run()        // 这里不可这样写,成递归了
 c.Animal.run() // 这是调用父结构体方法。
 fmt.Println("Cat run+++")
}

多态

Go语言不能像Java语言一样使用多态,但可以通过引入interface接口来解决。

复制代码
package main
import "fmt"
type Runner interface {
 run()
}
type Animal struct {
 name string
 age  int
}
func (*Animal) run() {
 fmt.Println("Animal run~~~")
}
type Cat struct {
 Animal // 匿名结构体嵌入
 color  string
}
func (c *Cat) run() {
 c.Animal.run()
 fmt.Println("Cat run+++")
}
type Dog struct {
 Animal // 匿名结构体嵌入
 color  string
}
func (d *Dog) run() {
 d.Animal.run()
 fmt.Println("Dog run+++")
}
func test(a Runner) { // 多态
 a.run()
}
func main() {
 // var a Animal = Cat{} // Go做不到这样赋值
 // a.run() // Go无法写出这2行,用接口
    
 d := new(Dog)
 d.name = "snoopy"
 test(d)
 c := new(Cat)
 c.name = "Garfield"
 test(c)
 test(d)
}
示例
复制代码

test使用同一个类型的同一个接口却表现不同,这就是多态。

posted on   自然洒脱  阅读(83)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
历史上的今天:
2019-07-05 k8s的核心对象
2019-07-05 K8S网络模型
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示