Go语言第九课 结构体与接口

Go是一门面向过程的语言,没有类。但是类似于C,有结构体。

Go语言还有一个神奇的地方,没有pubic或者private。包级元素+大写开头=可导出,可导出意味着包外可访问。

关于结构体

关于“继承”

其实Go里面没有继承,有的只是struct的嵌入(官方叫法“嵌入”)

package inheritance

import "fmt"

type FatherClass struct {
	Name string
	Age  int
}

func (this FatherClass) DoHello() {
	fmt.Println(this.Name + " --> say fuck hello")
}
package inheritance

type SonClass struct {
	FatherClass
	SchoolName string
}
package main

import (
	"./inheritance"
	"fmt"
)

func main() {
	son := inheritance.SonClass{}
	son.Name = "aaa"
	son.Age = 11
	son.SchoolName = "bbb"
	son.DoHello()
	son.FatherClass.DoHello()
	fmt.Println(son.DoHello)
	fmt.Println(son.FatherClass.DoHello)
}

aaa --> say fuck hello
aaa --> say fuck hello
0x4877f0
0x4877f0
 

但是值得注意的是

package main

import (
	"./inheritance"
)

func main() {
	son := inheritance.SonClass{}
	son.Name = "aaa"
	son.Age = 11
	son.SchoolName = "bbb"
	son.DoHello()

	var father inheritance.FatherClass
	father=son
	father.DoHello()
}

father=son会导致错误

cannot use son (type inheritance.SonClass) as type inheritance.FatherClass in assignment

说明Go里面的包含只是具有继承的语法些特征而已,并不是继承!!!

结构体的成员变量

结构体的成员变量可以是预定义类型也可以是结构体类型。

加入现在有个人,他有他自己的教育背景。我们再描述这种逻辑关系时可以使用结构体如下:

type edu_info struct {
	stu_num     string
	school_name string
	stu_years   int
}

type persion struct {
	name string
	edu  edu_info
}

需要注意的是:

· 结构体的成员变量会被赋予“默认初值”。而结构体自身的“默认初值”是所有成员变量“默认初值的集合”

· 结构体的成员变量用点“.”访问

· 最神奇的一点:对结构体值指针的点操作和对结构体值的点操作是等价的

· 如果结构体成员变量是大写开头的,则这个成员变量是可导出的。可导出意味着在包外可访问

· 一个聚合类型的元素不能是自身类型,但是可以是自身类型的指针。结构体也是聚合类型,同样遵循这样的规则。

关于空结构体

没有任何成员的结构体就是空结构体,它的大小为0,不包含任何信息。空结构体通常起到了占位的作用。

示例代码1

package main

import "fmt"

type edu_info struct {
	stu_num     string
	school_name string
	stu_years   int
}

type persion struct {
	name string
	edu  edu_info
}

func main() {
	var yong persion
	yong.name = "yuyong"
	yong.edu.school_name = "a school"
	yong.edu.stu_num = "001"
	fmt.Println(yong.edu.stu_num)
	fmt.Println(yong.edu.stu_years)

	var p_edu *edu_info = &yong.edu
	fmt.Println(p_edu.school_name)
	fmt.Println((*p_edu).school_name)

	var empty_struct struct{}
	fmt.Println(empty_struct)
}

结果:

001
0
a school
a school
{}

结构体的赋值

顺序赋值

yong := persion{"yuyong", edu_info{"0001", "a school", 4}}

对应赋值

yong_1 := persion{edu: edu_info{"0001", "a school", 4}, name: "yuyong"}

示例代码2

package main

import "fmt"

type edu_info struct {
	stu_num     string
	school_name string
	stu_years   int
}

type persion struct {
	name string
	edu  edu_info
}

func main() {
	yong := persion{"yuyong", edu_info{"0001", "a school", 4}}
	yong_1 := persion{edu: edu_info{"0001", "a school", 4}, name: "yuyong"}
	fmt.Println(yong)
	fmt.Println(yong_1)
}

运行结果

{yuyong {0001 a school 4}}
{yuyong {0001 a school 4}}

匿名成员

匿名成员是只有类型没有变量名的成员。

示例代码3

package main

import "fmt"

type edu_info struct {
	stu_num     string
	school_name string
	stu_years   int
}

type position struct {
	pos_name string
	phone    string
}

type persion struct {
	name string
	edu  edu_info
	int
	position
}

func main() {
	yong := persion{"yuyong", edu_info{"0001", "a school", 4}, 100, position{"Management", "110"}}
	yong_1 := persion{edu: edu_info{"0001", "a school", 4}, name: "yuyong"}
	yong_1.position.pos_name = "HR"
	yong_1.phone = "1110"
	yong_1.int = 100
	fmt.Println(yong)
	fmt.Println(yong_1)
}

{yuyong {0001 a school 4} 100 {Management 110}}

{yuyong {0001 a school 4} 100 {HR 1110}}

关于接口

接口的定义与实现

package main

import (
	"fmt"
	"strconv"
	"reflect"
)

type persion interface {
	sayHello(hello_word string) string
	sayFuck(hello_word string) string
}

type stu struct {
	name        string
	school_name string
}

type teacher struct {
	teacher_id string
	years      int
}

func (t teacher) sayHello(hello_word string) string {
	return "my tech id is " + t.teacher_id + " and hello --> " + hello_word
}

func (s stu) sayHello(hello_word string) string {
	return "my stu name is " + s.name + " and hello --> " + hello_word
}

func (t teacher) sayFuck(hello_word string) string {
	return "my tech id is " + t.teacher_id + " and fuck --> " + hello_word
}

func (s stu) sayFuck(hello_word string) string {
	return "my stu name is " + s.name + " and fuck --> " + hello_word
}

func main() {
	stu_test := new(stu)
	stu_test.name = "yuyong"
	stu_test.school_name = "a school"
	teh_test := new(teacher)
	teh_test.teacher_id = "1001"
	teh_test.years = 4

	var people [2]persion
	people[0] = stu_test
	people[1] = teh_test

	for i := 0; i < len(people); i++ {
		fmt.Println(reflect.TypeOf(people[i]))
		check := people[i].(persion)
		fmt.Println(check)
		fmt.Println(people[i].sayHello(strconv.Itoa(i)))
	}
}

*main.stu
&{yuyong a school}
my stu name is yuyong and hello --> 0
*main.teacher
&{1001 4}
my tech id is 1001 and hello --> 1

接口的嵌入

package main

import "fmt"

type interface_1 interface {
	func_1(string) string
}

type interface_2 interface {
	interface_1
	func_2(string) string
}

type class_2 struct {
}

func (this *class_2) func_2(input string) string {
	str := "22222222222-->" + input
	fmt.Println(str)
	return str
}

func (this *class_2) func_1(input string) string {
	str := "11111111111-->" + input
	fmt.Println(str)
	return str
}

func main() {
	p_class_2 := new(class_2)
	p_class_2.func_1("aaaa")
	p_class_2.func_2("bbbb")

	var p_interface_1 interface_1 = p_class_2
	var p_interface_2 interface_2 = p_class_2

	p_interface_1.func_1("cccc")

	p_interface_2.func_1("eeee")
	p_interface_2.func_2("ffff")
}

11111111111-->aaaa
22222222222-->bbbb
11111111111-->cccc
11111111111-->eeee
22222222222-->ffff

在指针上实现接口和在类型上实现接口的区别

package reflect

import (
	"testing"
	"fmt"
)

type IStudent interface {
	getName() string
	setName(_name string)
}

type SchoolChild struct {
	name        string
	age         int
	school_name string
}

func (this *SchoolChild) getName() string {
	return this.name
}

func (this *SchoolChild) setName(_name string) {
	this.name = _name
}

type MiddleSchoolStudent struct {
	name               string
	age                int
	middle_school_name string
}

func (this MiddleSchoolStudent) getName() string {
	return this.name
}

func (this MiddleSchoolStudent) setName(_name string) {
	this.name = _name
}

func TestType(t *testing.T) {
	var yong IStudent = &SchoolChild{"yuyong", 10, "USC"}
	fmt.Println(yong.getName())

	var guo IStudent = MiddleSchoolStudent{"guoqing", 20, "HMYZ"}
	fmt.Println(guo.getName())
}

func TestCopy(t *testing.T) {

	yong := MiddleSchoolStudent{"yuyong", 10, "USC"}
	var i_yong IStudent = yong
	i_yong.setName("feifei")
	fmt.Println(yong.getName())

	guo := SchoolChild{"guoqing", 20, "HMYZ"}
	var i_guo IStudent = &guo
	i_guo.setName("benben")
	fmt.Println(guo.getName())

}

yuyong
guoqing
yuyong
benben

 

 

你可能感兴趣的:(Golang)