Go语言中面向对象

Go语言面向对象:

   Go语言中没有明确的OOP(Object Oriented Programming)概念,
   Go语言中只提供了两个关键类型:struct和interface,struct与C++的普通类相似,interface对应的是抽象类的类型。
   面积对象是借助struct结构体实现的,interface则是定义接口的。

一、类的封装

示例讲解:

首先我们定义一个汽车的struct:汽车结构里面包括:品牌、型号和颜色成员组成。变量名小写为私有成员变量,变量名大写开头为公有成员变量。

type Car struct {
	brand      string // 品牌
	model      string // 型号
	color      string // 颜色
	energyType string // 能源类型
}

在Go语言中我们一般情况下使用New+结构体名称的规则来定义构造方法。

// 构造方法
func NewCar(brand, model, color, energyType string) *Car {
	return &Car{
		brand:      brand,
		model:      model,
		color:      color,
		energyType: energyType,
	}
}

接下来我们定义一个类成员方法:

// 获取car的信息
func (c *Car) GetCarInfo() {
	fmt.Printf("Car's Brand is : %s, Model is %s, Color is : %s, Energy Type : %s \n",
		c.brand, c.model, c.color, c.energyType)
}

该方法用于获取Car的信息,打印出所有类成员变量的值,func和方法名之间的“c *Car”是指针类型,说明函数是Car结构的方法,如果使用指针方式是为了需要修改类成员值,非指针时不能覆盖成员变量的值。

我们来测试一下上面的程序:

var car = NewCar("丰田", "凯美瑞", "黑色", "汽油")
car.GetCarInfo()

输出结果:

Car's Brand is : 丰田, Model is 凯美瑞, Color is : 黑色, Energy Type : 汽油

我们可以看到,我们私有成员变量的值在构造的时候被修改了,在调用打印的时候被输出出来了。

二、类的继承:

像PHP语言中需要使用extends来集成,Go语言中没有显示的类的继承,我们可以通过组合的形式来实现类的继承。

type EnergyTypeCar struct {
	Car
	SpeedUp string // 定义加速,我们假设是百公里加速。
}

func (et *EnergyTypeCar) GetEnergyTypeInfo() {
	fmt.Printf("我是新型汽车类,我的百公里加速为:%s\n", et.SpeedUp)
}

我们定义一个EnergyTypeCar类,通过组合的方式集成于Car,并有自己的类成员为SpeedUp来表示百公里加速。我们运行上面的代码结果为:

{{北汽新能源 EC5 白色 纯电} 10s}
我是新型汽车类,我的百公里加速为:10s
Car's Brand is : 北汽新能源, Model is EC5, Color is : 白色, Energy Type : 纯电

我们可以看到,组合后除了集成了Car以外,还新增了自己的成员变量和方法。

三、类的多态

多态是运行时的特性,而继承是编译时的特性。继承关系在编译的时候就就是已经确定的,而多态是运行的时候动态绑定的。

苹果手机和安卓手机都属于手机,具备打电话、发短信和上网的功能,我们把他们共同的属性抽象成接口表达:

// 定义手机功能
type Phone interface {
	Call(to string)        // 打电话
	SendMessage(to string) // 发短信
	OnInternet()           // 上网
}

苹果手机:

type IPhone struct{}

func (p *IPhone) Call(to string) {
	fmt.Printf("使用IPhone手机打电话给:%s\n", to)
}
func (p *IPhone) SendMessage(to string) {
	fmt.Printf("使用IPhone手机发短信给:%s\n", to)
}
func (p *IPhone) OnInternet() {
	fmt.Println("使用IPhone手机上网")
}

安卓手机:

type Android struct{}

func (p *Android) Call(to string) {
	fmt.Printf("使用Android手机打电话给:%s\n", to)
}
func (p *Android) SendMessage(to string) {
	fmt.Printf("使用Android手机发短信给:%s\n", to)
}
func (p *Android) OnInternet() {
	fmt.Println("使用Android手机上网")
}

多态实现:

	var iphone = IPhone{}
	iphone.Call("User 1")
	iphone.SendMessage("User 2")
	iphone.OnInternet()

	fmt.Println()

	var android = Android{}
	android.Call("User 2")
	android.SendMessage("User 2")
	android.OnInternet()

运行结果:

使用IPhone手机打电话给:User 1
使用IPhone手机发短信给:User 2
使用IPhone手机上网

使用Android手机打电话给:User 2
使用Android手机发短信给:User 2
使用Android手机上网

到这里面我们可以看到,通过抽象的接口,以及实现接口方法的具体类型的方式,Go语言实现了运行时的动态绑定,这就是所谓的抽象与多态。

发布了161 篇原创文章 · 获赞 23 · 访问量 24万+

猜你喜欢

转载自blog.csdn.net/guichenglin/article/details/105634635
今日推荐