GO 面向对象编程,你了解吗?

128 阅读4分钟

Go 和 Java 不同,他没有类(class)的概念,但这并不是说Go不支持面向对象编程,毕竟面向对象是一种思想。

面向对象三大基本特征

  • 封装:隐藏对象属性和实现细节,仅对外提供公共访问方式
  • 继承:使子类继承父类的属性和方法,或者是子类重写父类的属性和方法
  • 多态:不同对象中同种行为不同的实现方式

封装

Go 语言中可以使用结构体对属性进行封装。结构体好比类的一种简化形式,比如我们定义一个学生,学生有名字和性别,就像下面这样我们就定义了一个学生的结构体。不过结构体当中只定义了属性这点和 Java 就有这很大的差别,Java的属性和方法都是定义再类当中的,但是在 Go 当中 声明结构体,结构体中只声明了属性,方法却是在结构体之外。

属性

结构体里面定义了两个属性,并声明类型,现在属性有了是不是还缺少方法呢?别急,我们看下面

type Student struct {
	Name string
	age  int
}

方法

这里定义了一个吃饭的方法,创建对象以后,通过对象调用方法,

package main

import "fmt"

func main() {
	stu := Student{"zhang", 12}
	fmt.Println(stu.Eat()) // zhang正在东西
}

type Student struct {
	Name string
	age  int
}

func (stu *Student) Eat() string {
	return stu.Name + "正在东西"
}

关于访问权限的问题

在 GO 中是没有 public、private 等等这些权限修饰符的。

那么GO是通过什么来实现权限控制的呢?

原来在GO当中,通过定义变量、常量、类型、结构体、函数等的名称就可以控制访问权限了,首字符大写就相当于public,允许其他包访问,如果是小写的话,相当于private,只能在当前包中使用。学到这里想必你已经清楚如何定义和私有化结构体属性了,然后就可以封装set、get方法了。

继承

Go 中没有 extents 关键字,而是在结构体中内嵌匿名字段来实现继承,下面直接写了一个示例来展示这个关系,这样写的话,需要在 Student 初始化赋值的时候,也要将 People 初始化赋值。

package main

import "fmt"

type People struct {
	name string
}

// 人类描述吃的方法
func (p People) eat() {
	fmt.Println(p.name + "正在吃东西")
}

// 模拟构造方法
func newPeople(name string) *People {
	return &People{name: name}
}

// 匿名属性继承
type Student struct {
	*People
}

// 模拟构造方法
func newStudent(name string) *Student {
	return &Student{
		People: newPeople(name),
	}
}

func main() {
	stu := newStudent("zhangsan")
	stu.eat()
// 打印:zhangsan正在吃东西
}

多态

在面向对象中多态是由不同对象的同种行为的不同实现方式。

package main

import "fmt"

// 定义人的工作行为
type People interface {
	task()
}
// 定义老师结构体
type Teacher struct {
	taskName string
}

func (t Teacher) task() {
	fmt.Println("老师的工作是:" + t.taskName)
}
// 定义学生结构体
type Student struct {
	taskName string
}

func (s Student) task() {
	fmt.Println("学生的工作是:" + s.taskName)
}

func main() {
	t := &Teacher{"教书育人"}
	s := &Student{"好好学习"}

	// 这里向上赋值,在这个切片里,t 和 s 都是 People 类型了
	p := []People{t, s}
	for i, _ := range p {
		p[i].task()
	}
}

// 老师的工作是:教书育人
// 学生的工作是:好好学习

代码解析

我们定义了两个 task() 函数,分别为老师的任务和学生的任务,于是定义了一个包含 task() 的 People 接口,让 老师和学生 的两个函数都实现这个接口的函数。最后输出结果都执行了各自的任务,展现了多态的特征。

结尾

我是从 Java 转到 Go 的,我觉的 Go 的面向对象用起来没 Java 那么清晰明了,感觉有点混乱哈(不知道是不是不习惯的原因😁),然后就是,做项目的话,还是要看需求再决定是否使用**面向对象,**因为有的时候项目并不复杂完全没有必要使用继承多态等等,反而会增加项目的复杂度(有一个例子就是我前两天在写一个清单小程序的时候,封装了下get set 还有 继承接口这些,感觉完全没必要,直接写就好啦,看着还简洁呢)。

总体来说还是看需求哈,不能盲目的使用😊