文章目录
前言
今天早上把一个学姐送到车站,回来的路上突然很感慨,时光飞逝,我都已经大三了。明年这个时候就面临着毕业,要抓紧学习,提升自己!😄
想学Go语法基础篇的可以先看博主的一起学Go的系列文章!
GoLang面向对象类的表示与封装
面向对象的基本特征?
对象?哪里有对象?小姐姐小哥哥都在哪里?男生如果要找对象很简单!学习下图即可!😄
当然,这里指的对象,肯定不是男女朋友之间的关系,而是一种类的抽象。
三大特征:封装,继承,多态
Go中如何定义对象?
Go中利用 struct 结构体来代表某一个对象,结构体里面有对象的属性,在当前的.go文件中定义对该结构体的 get/set 方法,要注意的是,在写 struct 的 set 方法的时候,要用指针进行传值,因为 Go 中的 this 是当前对象的一个副本,并不是真正的对象引用,这点要注意。
简单实例代码
package main
import "fmt"
//如果类名首字母大写,则其他包也可以访问
//利用 struct 来描述一个对象
type Hero struct {
//如果属性名的首字母是大写,表示该属性是对外可以访问到的,否则只能在当前包的内部访问
//对应的属性
Name string
Age int
Level int
}
// 这里加不加指针区别不大,都可以获得到原来的值
func (this *Hero) GetName() string {
return this.Name
}
//这里要注意,函数形参中的结构体变量是用指针的方式传递的
func (this *Hero) SetName(name string) {
this.Name = name
}
func main() {
//创建一个对象
hero := Hero{Name: "zhangsan",Age:18, Level: 1}
fmt.Println(hero)
hero.SetName("lisi")
fmt.Println(hero)
}
如何区分对象的属性为私有(private)还是公有(public)?
利用对象中定义的属性的变量名的第一个字母大小写来区分,大写的为公有,小写的为私有,比如上面的代码中定义的 Hero,第一个字母 H 为大写,则这个对象可以被其他.go文件访问,其中的 Name 属性 第一个字母为 大写 N 则可以直接使用 hero.Name = “xxx” 的方式赋值,而不用通过 set 封装方法进行赋值,同理,在Go语言中,函数的访问权限也遵守这个规则,函数名的第一个字母是大写,则这个函数可以被另外的 .go 文件访问。
GoLang中的继承
通过在结构体的第一行写上要继承的父类结构体名称
继承实例代码
package main
import "fmt"
//定义一个父类对象
type Man struct {
name string
id int
}
//定义子类对象继承父类对象
type SuperMan struct {
Man //这里第一行写要继承的父类对象的结构体名称
level int //写子类自己的属性
}
//定义父类的 Eat() 方法
func (this *Man) Eat(){
fmt.Println("Eat.....")
}
//定义子类方法重写父类的 Eat() 方法
func (this *SuperMan) Eat(){
fmt.Println("Child Eat...")
}
func main() {
//定义一个父类对象
man := Man{name:"parent",id:1}
man.Eat()
//创建一个子类对象(子类对象里面传入父类对象)
superMan := SuperMan{man,123}
superMan.Eat()
}
打印结果
那么到这里,是不是觉得 Go 语言创建子类对象很复杂呢?还要特地传一个父类对象给子类对象作为构造方法的参数,有疑问就对了,带着问题学习是最高效的学习方式。其实GoLang中也可以直接让子类对象直接使用父类对象的属性
实例代码
package main
import "fmt"
//定义一个父类对象
type Man struct {
name string
id int
}
//定义子类对象继承父类对象
type SuperMan struct {
Man //这里第一行写要继承的父类对象的结构体名称
level int //写子类自己的属性
}
//定义父类的 Eat() 方法
func (this *Man) Eat(){
fmt.Println("Eat.....")
}
//定义子类方法重写父类的 Eat() 方法
func (this *SuperMan) Eat(){
fmt.Println("Child Eat...")
}
func main() {
//定义一个父类对象
//man := Man{name:"parent",id:1}
//man.Eat()
//创建一个子类对象(子类对象里面传入父类对象)
//superMan := SuperMan{man,123}
//直接创建一个子类对象
superMan := SuperMan{}
//这里可以直接使用 父类对象的 属性
superMan.name = "child!"
superMan.id = 1
//也可以直接使用 子类对象的 自身属性
superMan.level = 1
fmt.Println(superMan)
}
打印结果
GoLang中的多态
通过 interface 来定义,具体直接看代码
多态实例代码
package main
import "fmt"
//定义一个接口
type AnimalInterface interface {
Sleep()
Eat()
GetColor() string
}
//如果要使一个类实现某个接口,在Go语言中则让这个类实现该接口的全部方法即可,如下实例
//定义一个类,实现上面接口的全部方法
type Cat struct {
color string
}
func (this *Cat) Sleep() {
fmt.Println("Cat Sleep...")
}
func (this *Cat) Eat() {
fmt.Println("Cat Eat...")
}
func (this *Cat) GetColor() string {
return this.color
}
//定义Dog类实现接口
type Dog struct {
color string
}
func (this *Dog) Sleep() {
fmt.Println("Dog Sleep...")
}
func (this *Dog) Eat() {
fmt.Println("Dog Eat...")
}
func (this *Dog) GetColor() string {
return this.color
}
//多态的体现,传入接口,不传入接口的具体实现对象(工厂模式)
func showAnimal(animal AnimalInterface) {
animal.Eat()
animal.Sleep()
fmt.Println(animal.GetColor())
}
func main() {
cat := Cat{color:"red"}
dog := Dog{color:"red"}
//这里要注意要传递 对象的地址,因为接口实际上是一个指针
showAnimal(&cat)
showAnimal(&dog)
}
打印结果
interface{}万能数据类型
interface{} 空接口传入函数当作形参的时候,可以接受任意类型的参数
类似 Java 中的 Obejct 超类作为参数的时候,可以传递 String, 也可以传递 Integer等对象
实例代码
package main
import "fmt"
type Hero struct {
name string
}
//interface{} 是万能数据类型
func test(args interface{}) {
fmt.Println(args)
// interface{} 该如何区分?此时引用的底层数据结构类型是什么?
// 答案: 通过 "类型断言" 的机制来区分
result,ok := args.(string)
if ok {
fmt.Println("arg is string type, value = ",result)
fmt.Printf("value type is %T\n",result)
} else {
fmt.Println("arg is not string type!")
}
}
func main() {
s1 := "string"
s2 := 100
s3 := Hero{name:"string"}
test(s1)
test(s2)
test(s3)
}
打印结果
后记
Go语言系列还会继续更新,希望能和大家们一起继续学习!大家都要奋斗努力呀!😄
希望学到的童鞋可以给博主点个赞!👍👍
坚持分享,坚持原创,喜欢博主的靓仔靓女们可以看看博主的首页博客!
您的点赞与收藏是我分享博客的最大赞赏!
博主博客地址: https://blog.csdn.net/weixin_43967679