Golang Go语言中关于如何实现抽象类
假设现在我们定义了一个接口I
,有两个方法Foo
,Bar
, 结构体Parent
实现了 Foo
,而Bar
作为抽象方法由子类实现,
示例代码如下:
package main
type I interface {
Foo()
Bar()
}
type Parent struct {
I
}
func (p *Parent) Foo() {
p.Bar()
}
type Child struct {
Parent
}
func (c *Child) Bar() {
fmt.Println(“Child.Bar()”)
}
func main() {
c := &Child{
Parent: Parent{},
}
c.I = c // 如果注释掉这几句会提示空指针异常
c.Foo()
}
输出如下:
Child.Bar()
问题:
1.上面的代码实现了类似Java
风格的抽象类,但是在main
方法中的这句代码没看懂c.I = c
,这句代码的本质是做了什么事情?为什么c.I = c
就会报空指针异常
Golang Go语言中关于如何实现抽象类
更多关于Golang Go语言中关于如何实现抽象类的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
你不觉得你为了在 go 实现 java 的抽象类 写的很别扭么?
更多关于Golang Go语言中关于如何实现抽象类的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
不要用 Java 的思维来写 Go.
理解好 Go Interface 接口使用. 就够了.
之所以只有 Java 语言, 特别爱强调设计模式, 是 Java 的设计缺陷, 才需要显式打补丁(不是优点, 不要搞反了).
其他语言, 设计模式, 早就融入语言本身的设计.
Go Interface, 是面向接口编程的典范. 非常漂亮. 兼顾优雅 /简洁 /易用.
理解 Go 很简单. 核心就 2 点. 面向接口(interface) + 面向队列(channel) 编程. (沙雕泛型 generic, 先跳过)
面向接口(interface) = 面向动作(action), 数据和操作分离. 聚焦对操作(action)作抽象. 以操作为主, 数据来适配操作.
面向队列(channel) = MQ(kafka) = 生产者 /消费者模型. 你可以把 go channel, 当成内置的 kafka 来理解, 使用方式也一样.
so. go 的精华, 只有这么多. 剩下的部分, 都是裁剪 c 语言. (垃圾泛型除外)
你把 I 放到 parent 里是个什么意思。。。。
你把内嵌结构体理解成继承 /接口实现了。看看 embeded struct
本质上是让 Parent 继承 I 接口的具体实现,从而实现调用到子类的实现。。不过这样写实在是太奇怪了。。。
PS:go 设计的只有简单与漂亮\简单不沾边
漂亮\优雅
近几年新出来的一些语言,不要参考 java 来学习
这样写可以实现这功能,但是底层原理不知道为什么
多说一句. Go 和 Rust 等更现代的语言设计, 都是重视 组合 /嵌套 > 类继承.
Go 的 接口(interface) 设计, 都是 组合
的方式来扩展功能.
不要被 类继承
束缚思维. 类继承
, 是糟糕的东西.
不要总是想定义很大的类 struct (数据+方法过多).
尽量切分小类. 标准化操作 = 抽象接口方法(interface).
另外, go struct{}, 可以作为命名空间 namespace 使用 = 裸类(没数据, 只有方法).
小模块, 搭积木, 自由组合. 可以写出非常干净 /清晰的代码.
理性状态: 接口设计(interface) 和 数据(data), 应该是正交的.
推荐读 go-micro 这个项目源码来学习如何写 go + 设计大型框架系统.
go-micro 的代码写的非常非常漂亮.
不要用设计模式去包裹 go, 那不是它
在Go语言中,并没有像Java或C++那样的传统面向对象编程中的“抽象类”概念。不过,Go语言通过接口(interface)和结构体(struct)的组合,可以实现类似抽象类的功能。
接口在Go中是一种类型,它规定了对象的行为。一个接口可以包含多个方法,但不包含这些方法的实现。结构体则是一种可以包含字段和方法的复合数据类型。
要实现类似抽象类的功能,你可以定义一个接口,然后在不同的结构体中实现这个接口。这样,你就可以通过接口来引用实现了该接口的结构体,从而实现多态性。
例如,你可以定义一个“Shape”接口,它有一个“Draw”方法。然后,你可以创建不同的结构体,如“Circle”和“Rectangle”,并在这些结构体中实现“Draw”方法。这样,你就可以通过“Shape”接口来引用这些结构体,并调用它们的“Draw”方法,而无需知道它们的具体类型。
此外,Go语言还允许你在接口中嵌入其他接口,从而创建更复杂的接口层次结构。这进一步增强了Go语言在模拟抽象类方面的能力。
总的来说,虽然Go语言没有直接的抽象类概念,但通过接口和结构体的组合,你可以实现类似的功能,并享受Go语言简洁、高效的编程风格。如果你对具体的实现方式有疑问,欢迎继续提问。