Go的面向对象

Go语言没有对象的概念,没有生产对象的关键字,但是go语言的特性却可以用原生语法来模拟面向对象的特性。

面向对象的特征是:继承,一种联结类的层次模型;封装,把过程和数据包围起来,对数据的访问只能通过已定义的api;多态,父类中定义的属性或方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为。

抽象

面向对象的抽象性就是把现实世界中的某一类东西,提取出来,用程序代码表示,抽象出来的一般叫做类或者接口。

/**
动物类
*/

type Animals struct {
	name string //动物名称
	eat  string //动物食性
}
/**
动物接口
*/

type AnimalsAbstractMethod interface{
	showColor() string   //动物颜色
	showteech() string   //动物牙齿
	showlocation() string //生活地区

}

在go语言中结构体是属性的集合,结构体只能有属性。接口是方法的集合,接口只能是抽象方法(没有方法体)。

继承

子类继承父类的属性和行为,并根据自己的需求来扩展行为 。

go语言没有class的概念,也就没有extend的用法。要实现模拟类的行为,就必须要有类的方法和属性,在go中结构体可以定义属性,方法可以指向结构体,接口可以定义抽象方法,因此也可以实现继承。

类行为

在go中继承就是结构体的嵌套,方法直接重写方法体即可。

//继承模拟

/*
结构体构造属性
*/

type Animals struct {
	name string //动物名称
	eat  string //动物食性
}

/*
方法构造类方法
*/

func (animals Animals) toString() string {
	return "Animals{" + animals.name + "," + animals.eat + "}"
}


/*
结构体嵌套模拟继承
*/

type Herbivore struct {
	animals Animals   //父类嵌套在类中提供父类的属性
	teech   string
}

/*
重写方法
*/

func (berbivore Herbivore) toString() string {
	return "Herbivore{name=" + berbivore.animals.name + ",eat=" + berbivore.animals.eat + "}"
}

/*
实例化
*/

h1 := Herbivore{
	animals: Animals{
		"狗子",
		"杂食动物",
	},
	teech: "尖锐的牙齿",
}

fmt.Println(h1)
fmt.Println(h1.toString())

在这里插入图片描述

接口行为

go中接口是抽象函数的集合,go在先类的概念是和其他语言是不一样的,是一种新的概念。用方法重写接口的抽象方法,指向继承类即可。

/*
动物接口
*/

type animalsBehavior interface {
	showColor() string    //动物颜色
	showlocation() string //生活地区
}

/*
实现接口的方法并指向结构体
*/
func (berbivore Herbivore) showColor() {
	fmt.Println("打印动物颜色")
}

func (berbivore Herbivore) showlocation() {
	fmt.Println("打印动物生活区域")
}

重写的方法指向某个结构体,则结构体的实例就可以使用重写的抽象方法。

h1 := Herbivore{
	animals: Animals{
		"狗子",
		"杂食动物",
	},
	teech: "尖锐的牙齿",
}

fmt.Println(h1)
fmt.Println(h1.toString())

//使用抽象方法
h1.showColor()
h1.showlocation()

在这里插入图片描述

封装

封装是面向对象的特征之一,是对象和类概念的主要特性。封装就是把过程和数据包围起来,对数据的访问只能通过已定义的API。

Go语言中函数是基本单位,在go语言中通过变量首字母的大小写控制访问权限,因此使用Go实现面向对象的功能是需要借助该特性。

Go语言的访问权限的控制没有Java那么严格,首字母的大小写只限制了包以外的访问权限,在包内都可以访问到。

如下所示定义四个目录:

在这里插入图片描述
Animals是父类,Herbivore是子类,main是主类,Test是测试类。

  • Animals报下go文件内容
package Animals

/**
动物类
*/

type Animals struct {
	Name string //动物名称
	Eat  string //动物食性
}

//方法指向动物结构体
func (animals Animals) makeAnimals(name string, eat string) {
	animals.Name = name
	animals.Eat = eat
}

func (animals Animals) toString() string {
	return "Animals{" + animals.Name + "," + animals.Eat + "}"
}

Animals结构体属性首字母大写,才能在其他目录访问到,编写了两个方法指向结构体。方法名首字母是小写的也就意味者外部包无法访问。

在主类中引入包,并调用

package main

import (
	"fmt"
	"unit4/src/class/Animals"
	//	"unit4/src/class/Herbivore"
)

func main() {

	var a1 = Animals.Animals{
		Name: "小狗",
		Eat:  "杂食动物",
	}

	fmt.Println(a1)
}

在这里插入图片描述
没有小写字母的方法,因此在外部包不能调用。

当将员包改为大写时,如下:

//方法指向动物结构体
func (animals Animals) MakeAnimals(name string, eat string) {
	animals.Name = name
	animals.Eat = eat
}

func (animals Animals) ToString() string {
	return "Animals{" + animals.Name + "," + animals.Eat + "}"
}

就可以调用方法了,

在这里插入图片描述

通过首字母的大小写完成了结构体方法和属性私有性的限定。

多态

父类中定义的属性或方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为。

在上述的案例中,再编写一个Animals包中定义一个接口,内容如下:

type Animals struct {
	Name string //动物名称
	Eat  string //动物食性
}

type animalsBehavior interface {
	ShowColor() string
	ShowHeight() float32
}

func (animals Animals) ShowColor() {
	fmt.Println("animals color")
}

func (animals Animals) ShowHeight() {
	fmt.Println("animals height")
}

在其继承类中,重写父类的方法

type Herbivore struct {
	Animals  Animals.Animals
	Location string
}

/*
重写父类方法
*/
func (animals Herbivore) ShowColor() {
	fmt.Println("颜色时黄色")
}

func (animals Herbivore) ShowHeight() {
	fmt.Println("体重30公斤")
}

在主类中生产实例并调用方法,

h1 := Herbivore.Herbivore{
	Animals: Animals.Animals{
		Name: "小狗",
		Eat:  "杂食动物",
	},
	Location: "主人家",
}
fmt.Println(h1)
h1.ShowColor()
h1.ShowHeight()



h2 := Herbivore.Herbivore{
	Animals: Animals.Animals{
		Name: "小2",
		Eat:  "杂食动物2",
	},
	Location: "主人家2",
}

fmt.Println(h2)
h2.ShowColor()
h2.ShowHeight()

在这里插入图片描述

通过不同的实例化和方法的重写使对象的不同实例表现不同的行为。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xvwen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值