面向对象主要是继承、封装、多态
在java中继承有抽象类的概念、多态有接口的概念、封装有对应的访问修饰符修饰
在go语言中不像java中有关键字定义的这么明确。那么go没有class、extend、implement、public、private等关键字,那么是如何面向对象的呢
在go中会以结构体类表示一个类
以结构体组合的方式来表示继承
如果一个结构体有某个接口的所有方法,那么就认为该结构体实现了该接口
至于public、private以首字母大小写来区分,首字母大写的所有包都能访问,小写的只能在本包内才能访问
下面以一个例子来解释go如何使用面向对象,如果你有java基础应该会比较熟悉下面的例子
package main
import "fmt"
type Bean struct {
beanName string
isSingle bool
}
// BeanFactory 定义BeanFactory接口
type BeanFactory interface {
registerBean(bean Bean)
getSingleBean(beanName string) Bean
}
// AbstractBeanFactory 定义AbstractBeanFactory抽象类实现BeanFactory接口
type AbstractBeanFactory struct {
// 单例池
singlePool map[string]Bean
}
// 实现接口注册bean方法
func (b *AbstractBeanFactory) registerBean(bean Bean) {
if bean.isSingle {
if nil == b.singlePool {
b.singlePool = make(map[string]Bean)
}
b.singlePool[bean.beanName] = bean
}
}
// 实现接口获取单例bean方法
func (b *AbstractBeanFactory) getSingleBean(beanName string) Bean {
return b.singlePool[beanName]
}
// ApplicationContext 具体业务实现类继承AbstractBeanFactory抽象类
type ApplicationContext struct {
AbstractBeanFactory
}
// 重写注册bean方法
func (b *ApplicationContext) registerBean(bean Bean) {
fmt.Println("ApplicationContext ... registerBean")
b.AbstractBeanFactory.registerBean(bean)
}
func main() {
bean := Bean{isSingle: true, beanName: "restTemplate"}
// 多态使用
var factory BeanFactory = &ApplicationContext{}
// 打印factory 类型
fmt.Printf("%T\n", factory)
factory.registerBean(bean)
fmt.Println(factory.getSingleBean("name"))
fmt.Println(factory.getSingleBean("restTemplate"))
}
从图片中goland的提示可以知道 AbstractBeanFactory 实现了BeanFactory接口,ApplicationContext重写了AbstractBeanFactory的registerBean方法
执行结果
*main.ApplicationContext
ApplicationContext ... registerBean
{ false}
{restTemplate true}
从结果中可以看出factory以接口类型BeanFactory接收一个具体子类对象ApplicationContext
执行 registerBean 方法实际上执行的是 ApplicationContext 的 registerBean 方法
执行getSingleBean方法,由于ApplicationContext没有该方法,会从父类 AbstractBeanFactory 找到该方法执行
到这go中面向对象的使用就介绍完了
欢迎关注,学习不迷路!