惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Security Latest
Security Latest
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Stack Overflow Blog
Stack Overflow Blog
WordPress大学
WordPress大学
N
Netflix TechBlog - Medium
GbyAI
GbyAI
云风的 BLOG
云风的 BLOG
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
宝玉的分享
宝玉的分享
博客园 - 【当耐特】
C
Cyber Attacks, Cyber Crime and Cyber Security
雷峰网
雷峰网
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
Threat Research - Cisco Blogs
NISL@THU
NISL@THU
Spread Privacy
Spread Privacy
P
Proofpoint News Feed
J
Java Code Geeks
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
MyScale Blog
MyScale Blog
T
Tor Project blog
P
Proofpoint News Feed
C
CERT Recently Published Vulnerability Notes
P
Privacy & Cybersecurity Law Blog
MongoDB | Blog
MongoDB | Blog
Simon Willison's Weblog
Simon Willison's Weblog
C
Cybersecurity and Infrastructure Security Agency CISA
L
LINUX DO - 热门话题
小众软件
小众软件
G
GRAHAM CLULEY
P
Privacy International News Feed
AWS News Blog
AWS News Blog
Know Your Adversary
Know Your Adversary
P
Palo Alto Networks Blog
人人都是产品经理
人人都是产品经理
S
Schneier on Security
Scott Helme
Scott Helme
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
B
Blog RSS Feed
T
The Exploit Database - CXSecurity.com
Recent Announcements
Recent Announcements
E
Exploit-DB.com RSS Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
U
Unit 42
The Register - Security
The Register - Security
S
Securelist
Martin Fowler
Martin Fowler
Project Zero
Project Zero
大猫的无限游戏
大猫的无限游戏
Cisco Talos Blog
Cisco Talos Blog

博客园 - 自然洒脱

MiniMax 权益码 Token Plan 套餐 9 折优惠 go语言context包 go语言通道 go语言GMP模型 go语言mongodb操作 go语言gorm的CRUD go语言gorm go语言mysql驱动 go语言log相关 go语言包管理 go语言时间相关 go语言序列化和反序列化 go语言结构体排序 go语言异常处理 go语言接口 go语言结构体(二) go语言结构体(一) go语言递归函数及defer go语言函数作用域及匿名函数
go语言的"面向对象"
自然洒脱 · 2023-07-05 · via 博客园 - 自然洒脱

面向对象定义

面向对象三要素:

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

实现了以上特征的语言,才能成为面向对象编程范式语言。 严格意义来说,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使用同一个类型的同一个接口却表现不同,这就是多态。