从0开始学GO之匿名组合与方法


更多参见: 从0开始学GO之目录

匿名组合

匿名字段与初始化

只提供类型,而不写字段名的方式,就是匿名字段,也称为嵌入字段。一般情况下,定义结构体的时候是字段名与其类型一一对应。

匿名字段也是一个结构体的时候,那么这个结构体所拥有的全部字段都被隐式地引入了当前定义的这个结构体

package main

import "fmt"

//人
type Person struct {
	name string
	sex  byte
	age  int
}

//学生
type Student struct {
	Person // 匿名字段,那么默认Student就包含了Person的所有字段
	id     int
	addr   string
}

//作家
type Writer struct {
	Person // 匿名字段
	books []string
	income int
}

func main() {
	//顺序初始化
	s1 := Student{Person{"张三", 'f', 18}, 1, "sz"}
	fmt.Printf("s1 = %+v\n", s1)  //  %+v   添加字段名(如结构体)
	//部分成员初始化1
	s2 := Writer{Person: Person{name:"李四", age: 39}, books :[]string {"book1","book2"}}
	fmt.Printf("s2 = %+v\n", s2)
	//顺序初始化
	s3 := Writer{Person{"王五", 'f', 18}, []string {"book11","book22"}, 123}
	fmt.Printf("s3 = %+v\n", s3)
}

在这里插入图片描述

成员的操作

成员赋值以及同名字段

package main

import "fmt"

//人
type Person struct {
	name string
	sex  byte
	age  int
}

//学生
type Student struct {
	Person // 匿名字段,那么默认Student就包含了Person的所有字段
	id     int
	addr   string
}

//作家
type Writer struct {
	Person // 匿名字段
	books []string
	income int
	name string // 和Person中的name同名 同名字段
}

func main() {
	var s1 Student //变量声明
	//给成员赋值
	s1.name = "张三" //等价于 s1.Person.name = "张三"
	s1.sex = 'm'
	s1.age = 18
	// s1.Person = Person{"张三", 'm', 18}
	s1.id = 1
	s1.addr = "sz"
	fmt.Println(s1) // {{张三 109 18} 1 sz}

	var w1 Writer //变量声明
	//给 Writer 的name,不会给Person赋值
	w1.name = "李四"
	fmt.Printf("%+v\n", w1) // {Person:{name: sex:0 age:0} books:[] income:0 name:李四}

	//默认只会给最外层的成员赋值
	//给匿名同名成员赋值,需要显示调用
	w1.Person.name = "王五"
	fmt.Printf("%+v\n", w1) // {Person:{name:王五 sex:0 age:0} books:[] income:0 name:李四}
}

在这里插入图片描述

其它匿名字段

所有的内置类型自定义类型 以及 结构体指针类型 都是可以作为匿名字段的:

package main

import "fmt"

//人
type Person struct {
	name string
	sex  byte
	age  int
}

type income int //自定义类型

//作家
type Writer struct {
	*Person // 匿名字段,结构体指针类型
	books [3]string
	income // 匿名字段,自定义类型
	string // 匿名字段, 内置类型
}

func main() {
	//初始化
	w1 := Writer{&Person{"张三", 'm', 18}, [3]string{"book1","book2"}, 321,"Hello World"}
	fmt.Printf("%+v\n", w1)
	fmt.Printf("%s, %c, %d\n", w1.name, w1.sex, w1.age)

	var w2 Writer
	w2.Person = new(Person) //先 分配空间
	w2.name = "李四"
	w2.sex = 'f'
	w2.age = 20

	//w2.books = []string{"book11","book22"}
	w2.books[0] = "book00"
	w2.books[1] = "book11"
	w2.income = 123
	w2.string = "Hello"

	fmt.Printf("%+v\n", w2)
	fmt.Printf("%s, %c, %d\n", w2.name, w2.sex, w2.age)
}

在这里插入图片描述

方法

在面向对象编程中,一个对象其实也就是一个简单的值或者一个变量,在这个对象中会包含一些函数,这种带有接收者的函数,我们称为方法(method)。 本质上,一个方法则是一个和特殊类型关联的函数。

一个面向对象的程序会用方法来表达其属性和对应的操作,这样使用这个对象的用户就不需要直接去操作对象,而是借助方法来做这些事情。

在Go语言中,可以给任意自定义类型(包括内置类型,但不包括指针类型)添加相应的方法。

⽅法总是绑定对象实例,并隐式将实例作为第⼀实参 (receiver)

func (receiver ReceiverType) funcName(parameters) (results)
  • 参数 receiver 可任意命名。如⽅法中未曾使⽤,可省略参数名。
  • 参数 receiver 类型可以是 T 或 *T。基类型 T 不能是接⼝或指针。
  • 不支持重载方法,也就是说,不能定义名字相同但是不同参数的方法。

为类型添加方法

为基础类型添加方法

package main

import "fmt"

type MyInt int //自定义类型,给int改名为MyInt

//在函数定义时,在其名字之前放上一个变量,即是一个方法
func (a MyInt) Add(b MyInt) MyInt { //面向对象
	return a + b
}

//传统方式的定义
func Add(a, b MyInt) MyInt { //面向过程
	return a + b
}

func main() {
	var a MyInt = 1
	var b MyInt = 1
	//调用func (a MyInt) Add(b MyInt)
	fmt.Println("a.Add(b) = ", a.Add(b)) //a.Add(b) =  2
	//调用func Add(a, b MyInt)
	fmt.Println("Add(a, b) = ", Add(a, b)) //Add(a, b) =  2
}

在这里插入图片描述

为结构体添加方法

package main

import "fmt"

//人
type Person struct {
	name string
	sex  byte
	age  int
}

type income int //自定义类型

//作家
type Writer struct {
	*Person // 匿名字段,结构体指针类型
	books [3]string
	income // 匿名字段,自定义类型
	string // 匿名字段, 内置类型
}


func (w Writer) MyPrint(n int) string{
	fmt.Printf("-------%d-----\n",n)
	fmt.Printf("Name:%s, Sex:%c, Age:%d\n", w.name, w.sex, w.age)
	fmt.Println("Books: ", w.books, "\tIncome: ",w.income,"\t",w.string)
	return "Writer - MyPrint"
}

func main() {
	//初始化
	w1 := Writer{&Person{"张三", 'm', 18}, [3]string{"book1","book2"}, 321,"Hello World"}
	fmt.Println(w1.MyPrint(123))
}

在这里插入图片描述

值语义和引用语义

参见: 从0开始学GO之函数

匿名字段方法的继承与重写

如果匿名字段实现了一个方法,那么包含这个匿名字段的struct也能调用该方法。匿名字段中的同名方法需要显示调用。

package main

import "fmt"

//人
type Person struct {
	name string
	sex  byte
	age  int
}

type income int //自定义类型

//作家
type Writer struct {
	*Person // 匿名字段,结构体指针类型
	books [3]string
	income // 匿名字段,自定义类型
	string // 匿名字段, 内置类型
}

func (p Person)MyPrint(n int) string { // Person 方法
	fmt.Printf("--Person-----%d-----\n",n)
	fmt.Printf("Name:%s, Sex:%c, Age:%d\n", p.name, p.sex, p.age)
	return "Person - MyPrint"
}
func (p Person)MyPrint2() string{ // Person 方法
	fmt.Printf("名称:%s, 性别:%c, 年龄:%d\n", p.name, p.sex, p.age)
	return "Person - MyPrint2"
}


func (w Writer) MyPrint(n int) string{ // Writer 方法
	fmt.Printf("--Writer-----%d-----\n",n)
	fmt.Printf("Name:%s, Sex:%c, Age:%d\n", w.name, w.sex, w.age)
	fmt.Println("Books: ", w.books, "\tIncome: ",w.income,"\t",w.string)
	return "Writer - MyPrint"
}

func main() {
	//初始化
	w1 := Writer{&Person{"张三", 'm', 18}, [3]string{"book1","book2"}, 321,"Hello World"}
	fmt.Println(w1.MyPrint(123)) // 重写
	fmt.Println("=============")
	fmt.Println(w1.MyPrint2())  //  继承
	fmt.Println("=============")
	fmt.Println(w1.Person.MyPrint(321))
}

在这里插入图片描述

个人能力有限,如有错误或者其他建议,敬请告知欢迎探讨,谢谢!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

墨1024

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

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

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

打赏作者

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

抵扣说明:

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

余额充值