Go-21-结构体

Go语言的面向对象

其他编程语言大多使用关键字“类”(class)来定义封装对象,表示该类的具体特征,然而Go并不是一个纯面向对象的编程语言。Go语言采用更灵活的“结构体”替代了“类”。

Go语言并没有提供类(class),但是它提供了结构体(struct),方法(method)可以在结构体上添加。与类相似,结构体提供了捆绑数据和方法的行为。

Go语言没有继承,虚方法,构造方法和析构方法

虽然Go语言没有继承和多态,Go语言可以通过匿名字段实现继承通过接口实现多态。在Go语言中学习面向对象,主要学习结构体(struct)、方法(method)、接口(interface)。

定义结构体与实例化

结构体是由一系列相同类型或不同类型的数据构成的数据集合。

type 类型名 struct{
  成员属性1 类型1
  成员属性2 类型2
  成员属性3,成员属性4 类型3  
}

注意:

1. 类型名在同一个包下,不可以重复

2. 属性唯一

3. 结构体的定义只是一种内存布局的描述,只有当结构体实例化时,才会真正分配内存

结构体的初始化:

package main

import "fmt"

// 结构体
type Student struct {
name string
age int
sex byte
}
func main() {
//1.var 声明方式实例化结构体,初始化方式为:对象.属性=值
var s1 Student
fmt.Print(s1)
fmt.Printf("t1:%T,%v,%q \n",s1,s1,s1)
s1.name="sixinshuier"
s1.age=18
s1.sex=1
fmt.Println(s1)
//2. 变量简短方式声明实例化结构体
s2:=Student{}
s2.name="shuier"
s2.age=17
s2.sex=1
fmt.Println(s2)
//3. 变量简短
s3:=Student{
name:"sixinshui",
age:19,
sex: 1,
}
fmt.Println(s3)
//4.省略属性名
s4:=Student{"sixin",19,0}
fmt.Println(s4)
//5. 使用new内置函数实例化struct
s5:= new(Student)
fmt.Printf("stu:%T,%v,%p \n",s5,s5,s5)
(*s5).name="huahua"
(*s5).age=20
(*s5).sex=0
fmt.Println(s5)
//语法糖写法
s5.name="si"
s5.sex=21
s5.age=1
fmt.Println(s5)
}

结构体是值类型

结构体是值类型, 值类型是深拷贝,深拷贝就是为新的对象分配了内存。引用类型是浅拷贝,浅拷贝只是复制了对象的指针

 

package main

import "fmt"

type Flower struct {
    name string
    coler string
}
func main() {
    f1:=Flower{"百合","白色"}
    fmt.Printf("f1:%T,%v,%p \n",f1,f1,&f1)
    fmt.Println("#####################")
    //将结构体对象作为参数(值传递)
    changeFlower1(f1)
    fmt.Printf("f1:%T,%v,%p \n",f1,f1,&f1)
    fmt.Println("#####################")
    //将结构体指针作为参数参数传递
    changeFlower2(&f1)
    fmt.Printf("f1:%T,%v,%p \n",f1,f1,&f1)
    fmt.Println("#####################")
    //将结构体对象作为返回值
    f2:=getFlower1()
    f3:=getFlower1()
    fmt.Println(f2,f3)
    fmt.Println("#####################")
    f3.name="桃花"
    fmt.Println(f2,f3)
    fmt.Println("#####################")
    f4:=getFlower2()
    f5:=getFlower2()
    fmt.Println(f4,f5)
    f4.name="樱花"
    fmt.Println(f4,f5)
}
func getFlower1() (f Flower)  {
    f=Flower{"狗尾巴草","绿"}
    fmt.Printf("f1:%T,%v,%p \n",f,f,&f)
    return
}
func getFlower2() (f *Flower)  {
    f1:=Flower{"狗尾巴草","绿"}
    fmt.Printf("f1:%T,%v,%p \n",f1,f1,&f1)
    f=&f1
    return
}

//将结构体对象作为参数传递
func changeFlower1(f Flower){
    f.name="玫瑰"
    f.coler="紫色"
    fmt.Printf("func1:%T,%v,%p \n",f,f,&f)
    fmt.Println("#####################")
}

//将结构体指针作为参数传递
func changeFlower2(f *Flower)  {
    f.name="栀子花"
    f.coler="白色"
    fmt.Printf("func1:%T,%v,%p \n",f,f,&f)
    fmt.Println("#####################")
}

匿名结构体

匿名结构体就是没有名字的结构体,无须通过type关键字定义就可以直接使用。创建匿名结构体时,同时要创建对象。匿名结构体由结构体定义和键值对初始化两部分组成

变量名:=struct{
// 定义成员属性
}{//初始化成员属性}
f1:=struct{
name,coler string
}("康乃馨""")

结构体嵌套

将一个结构体作为另一个结构体的属性(字段),这种结构就是结构体嵌套。‘

结构体嵌套可以模拟面向对象编程中的以下两种关系。

• 聚合关系:一个类作为另一个类的属性。

• 继承关系:一个类作为另一个类的子类。子类和父类的关系。

 

type Person struct{
     Name string
     Age int  
}

type Student struct{
     *Person
      Number int
}

// 不推荐这种初始化,一旦struct增加字段,则整个初始化语句会报错
a:=Person{"TOM",21} 

//建议这种
p:=&Person{
   Name:"Tom",
   Age:12
}

s:=Student{
   Person:p,
   Number:110
}

 

posted @ 2020-05-28 15:18  sixinshuier  阅读(176)  评论(0编辑  收藏  举报