13.Go语言·面向对象编程应用(二)

main.go

// Go语言·面向对象编程应用
package main

//  包的本质是创建不同的文件夹
//  go的每一个文件都是属于一个包的
//  go以包的形式管理项目和文件目录。
//  import "包的路径"
import (
    model "day22/model"
    "fmt"
)

var content string = `
————————————————Go语言·面向对象编程应用————————————————————
一、工厂模式
    Golang的结构体,没有构造函数,利用工厂模式来获取一个实例
二、抽象
    一类事物的属性(字段)和行为(方法),提取出来,形成一个物理模型或数据模型(结构体)。

三、面向对象编程三大特性
    1.封装:抽象出来的字段和对字段的操作封装在一起,数据被保护在内部,程序的其他包只有通
    过被授权的操作(方法),才能对字段进行操作。
        a.隐藏实现细节
        b.可以对数据进行验证,保证安全合理
        c.对结构体中的属性进行封装
        d.通过包,可以对方法进行封装
    2.实现步骤:
        1.将结构体、字段(属性)的首字母小写
        2.给结构体所在包提供一个工厂模式的函数,首字母大写,供其他包使用。
        3.提供一个首字母大写的Set方法,用于对属性判读并赋值:
        func(var *结构体类型名) SetAttrName(参数列表) (返回值列表){
            // 
            var.attrName = 参数
        }
        4.提供一个字母大写的Get方法,用于获取属性的值
        func(var *结构体类型名) GetAttrName() {
            return var.attrName 
        }
        // 结构体指针
        var stu = model.NewStudent("周帅",19,"12345",1000) //&{Uzi 19}
        if stu != nil {
            fmt.Println("创建成功!")
        }else{
            fmt.Println("创建失败!")
            return 
        }
        stu.Recharge(100,"123456")
        stu.Withdraw(10,"123456")
    3.继承:
        1.代码的复用性,易维护,可扩展
        2.结构体可以使用嵌套匿名结构体所有的字段和方法,即方法和字段首字母大写或小写,
        都可以使用
        3.匿名结构体访问可以简化:
            // son.Father.Name="小可爱"
            // son.Father.Age=17
            // son.Father.Salary=1000
            // son.Father.Work(12000)
            // son.Father.Owner()
            
            // 匿名结构体字段访问可以简化如下:
            son.Name = "小美丽"
            son.Age  = 19
            son.Salary = 3000
            son.Work(15000)
            son.Owner()
            通过son访问字段或方法时候,其执行流程如下比如son.Name:
                1.编译器会先看son在对应类型Son有没有Name,如果有,则直接调用Son类型的
                Name字段。
                2.如果没有,就去Son中嵌入的匿名结构体Father找,如果有,就调用,如果没有
                就报错。
        4.当结构体和匿名结构体有相同的字段和方法时,编译器会采用就近原则访问,
            son.Work(15000)
            son.Owner()
        如果希望访问匿名结构体的字段和方法,可以通过匿名结构体名来区分
            son.Father.Work(12000)
            son.Father.Owner()
多重继承:
        5.结构体嵌入两个或多个匿名结构体,如果两个匿名结构体有相同的字段和方法:
            1.结构体本身没有同名的字段和方法时,在访问时,就需要明确指定匿名结构体名字,
            否则编译报错。
                son.Mother.Name="小甜点"
                son.Mother.Age=17
                son.Mother.Salary=1000
                son.Mother.Work(12000)
                son.Mother.Owner()
            2.结构体本身有同名的字段和方法,可以如下:
                son.Name = "小美丽"
                son.Age  = 19
                son.Salary = 3000
                son.Work(15000)
                son.Owner()
        6.如果一个struct嵌套咯一个有名的结构体,这种模式就是组合,如果是组合关系,那么
        在访问组合的结构体字段和方法时,就必须带上结构体的名字比如:
            type Son struct {
                // 嵌入一个匿名结构体:继承
                Father
                // 组合关系:嵌套咯一个有名的结构体
                Mom Mother
            }
            组合关系,在访问组合的结构体字段和方法时,就必须带上结构体的名字比如:
            son.Mom.Name="小狐狸"
            son.Mom.Age=17
            son.Mom.Salary=1000
            son.Mom.Work(12000)
            son.Mom.Owner()
        7.嵌套匿名结构体后,也可以在创建结构体变量(实例)时,直接指定各个匿名结构体字
        段的值。
        type Goods struct{
            Name string
            Price float64
        }

        type Brand struct{
            Name string
            Address string
        }

        type TV struct {
            Goods
            Brand
        }

        type Video struct {
            *Goods
            *Brand
        }

        tv1 := TV{
            Goods{"电视剧001",6777.99},
            Brand{"索尼","东京"},
        }

        tv2 := TV {
            Goods {
                Name:"电视剧002",
                Price:8888.99,
            },
            Brand{
                Name:"长虹",
                Address:"山东",
            },
        }

        vido1 := Video {
            &Goods {
                Name:"CD001",
                Price:1333.99,
            },
            &Brand{
                Name:"苹果",
                Address:"成都",
            },
        }

        vido2 := Video{
            &Goods{"CD002",3777.99},
            &Brand{"华为","福建"},
        }

`

type Goods struct{
    Name string
    Price float64
}

type Brand struct{
    Name string
    Address string
}

type TV struct {
    Goods
    Brand
}

type Video struct {
    *Goods
    *Brand
}


func main() {
    var son = &model.Son{}
    // son.Father.Name="小可爱"
    // son.Father.Age=17
    // son.Father.Salary=1000
    // son.Father.Work(12000)
    // son.Father.Owner()
    
    // 匿名结构体字段访问可以简化如下:
    // son.Name = "小美丽"
    // son.Age  = 19
    // son.Salary = 3000
    // son.Work(15000)
    // son.Owner()
    // 
    // 结构体嵌入两个或多个匿名结构体
    // son.Mother.Name="小甜点"
    // son.Mother.Age=17
    // son.Mother.Salary=1000
    // son.Mother.Work(12000)
    // son.Mother.Owner()
    // 
    // 嵌套咯一个有名的结构体
    son.Mom.Name="小狐狸"
    son.Mom.Age=17
    son.Mom.Salary=1000
    son.Mom.Work(12000)
    son.Mom.Owner()

    tv1 := TV{
        Goods{"电视剧001",6777.99},
        Brand{"索尼","东京"},
    }

    tv2 := TV {
        Goods {
            Name:"电视剧002",
            Price:8888.99,
        },
        Brand{
            Name:"长虹",
            Address:"山东",
        },
    }
    fmt.Println(tv1)
    fmt.Println(tv2)

    vido1 := Video {
        &Goods {
            Name:"CD001",
            Price:1333.99,
        },
        &Brand{
            Name:"苹果",
            Address:"成都",
        },
    }

    vido2 := Video{
        &Goods{"CD002",3777.99},
        &Brand{"华为","福建"},
    }


    fmt.Println(*vido1.Goods,*vido1.Brand)
    fmt.Println(*vido2.Goods,*vido2.Brand)


}

son.go

package model

import (
    _"fmt"
)

type Son struct {
    // 嵌入一个匿名结构体:继承
    Father
    Mom Mother
}


// func (son *Son) Owner() {
//  fmt.Printf("Son[%v]工资:%.2fRMB \n",son.Name,son.Salary)
// }

// func (son *Son) Work(money float64) {
//  son.Salary += money
//  fmt.Println("Son Salary So Good !")
// }

father.go

package model

import (
    "fmt"
)

type Father struct {
    Name string
    Age int
    Salary float64
}


func (dad *Father) Owner() {
    fmt.Printf("Father[%v]工资:%.2fRMB \n",dad.Name,dad.Salary)
}

func (dad *Father) Work(money float64) {
    fmt.Println("Father Salary So Good !")
    dad.Salary += money
}

mother.go

package model

import (
    "fmt"
)


type Mother struct {
    Name string
    Age int
    Salary float64
}


func (mum *Mother) Owner() {
    fmt.Printf("Mother[%v]工资:%.2fRMB  \n",mum.Name,mum.Salary)
}

func (mum *Mother) Work(money float64) {
    fmt.Println("Mother Salary So Good !")
    mum.Salary += money
}

你可能感兴趣的:(13.Go语言·面向对象编程应用(二))