go- Object-Oriented Programming (lower)

Object-oriented programming ideas - Abstract

Abstract presentation

In front of us to define a structure, when in fact that is the common property of a class of things (fields) and behavior (methods) to extract
out, forming a physical model (structure). This method is called an abstract study of the problem
, such as a bank account:

package main

import (
    "fmt"
)
//定义一个结构体Account
type Account struct {
    AccountNo string
    Pwd string
    Balance float64
}

//方法
//1. 存款
func (account *Account) Deposite(money float64, pwd string)  {

    //看下输入的密码是否正确
    if pwd != account.Pwd {
        fmt.Println("你输入的密码不正确")
        return 
    }

    //看看存款金额是否正确
    if money <= 0 {
        fmt.Println("你输入的金额不正确")
        return 
    }

    account.Balance += money
    fmt.Println("存款成功~~")

}

//取款
func (account *Account) WithDraw(money float64, pwd string)  {

    //看下输入的密码是否正确
    if pwd != account.Pwd {
        fmt.Println("你输入的密码不正确")
        return 
    }

    //看看取款金额是否正确
    if money <= 0  || money > account.Balance {
        fmt.Println("你输入的金额不正确")
        return 
    }

    account.Balance -= money
    fmt.Println("取款成功~~")

}

//查询余额
func (account *Account) Query(pwd string)  {

    //看下输入的密码是否正确
    if pwd != account.Pwd {
        fmt.Println("你输入的密码不正确")
        return 
    }

    fmt.Printf("你的账号为=%v 余额=%v \n", account.AccountNo, account.Balance)

}


func main() {

    //测试一把
    account := Account{
        AccountNo : "gs1111111",
        Pwd : "666666",
        Balance : 100.0,
    }

    //这里可以做的更加灵活,就是让用户通过控制台来输入命令...
    //菜单....
    account.Query("666666")
    account.Deposite(200.0, "666666")
    account.Query("666666")
    account.WithDraw(150.0, "666666")
    account.Query("666666")

    


}

Object-oriented programming three characteristics - Encapsulated

basic introduction

Golang still have inheritance, encapsulation and polymorphism characteristics of object-oriented programming, but the way to achieve and other OOP languages different
kind, let one by one to explain in detail how the three characteristics Golang is achieved for the students.

Package Introduction

Package (encapsulation) is to abstract the fields and field operations of the package together, within the data to be protected, the program which
it only packets, for the field can be operated by the authorized operator (Method)

Understanding and benefits package

1) hide implementation details
2) improve data verification, to ensure safe and reasonable (Age)

How to reflect package

1) the structure of the attribute package
2) by a process, the bag package implemented

Package implementation steps

1) A structure, a field (attribute) of the first letter in lower case (not export, and other packages can not be used, similar Private)
2) to provide a bag structure where the factory mode function, the first letter capitalized. Similarly a constructor
3) providing a method for the capitalized Set (similar to other languages public), and for determining the attribute assignment
func (var structure type name) setXXX (parameter list) (the returned list) {
// Add business logic data validation
var. = parameter field
}
4) providing a capitalized Get method (similar to other languages public), the value of the property for obtaining
func (var structure type name) GetXxx () {
return var .age;
}
special note: in golang development package and did not emphasize, this is not like Java java learned so remind friends.
do not always use java syntax features to look golang, golang itself object-oriented characteristics made simplified.

See a case

Please watch a program (person.go), not just to see the person's age, salary and other privacy, and enter the age of reasonable inspection
certificate. Design: model package (person.go) main package (main.go call the Person structure)
main.go

package main
import (
    "fmt"
    "go_code/code/chapter11/encapsulate/model"
)

func main() {

    p := model.NewPerson("smith")
    p.SetAge(18)
    p.SetSal(5000)
    fmt.Println(p)
    fmt.Println(p.Name, " age =", p.GetAge(), " sal = ", p.GetSal())
    
}

moudel

package model
import "fmt"

type person struct {
    Name string
    age int   //其它包不能直接访问..
    sal float64
}

//写一个工厂模式的函数,相当于构造函数
func NewPerson(name string) *person {
    return &person{
        Name : name,
    }
}

//为了访问age 和 sal 我们编写一对SetXxx的方法和GetXxx的方法
func (p *person) SetAge(age int) {
    if age >0 && age <150 {
        p.age = age
    } else {
        fmt.Println("年龄范围不正确..")
        //给程序员给一个默认值
    }
}

func (p *person) GetAge() int {
    return p.age
}


func (p *person) SetSal(sal float64) {
    if sal >= 3000 && sal <= 30000 {
        p.sal = sal
    } else {
        fmt.Println("薪水范围不正确..")
        
    }
}

func (p *person) GetSal() float64 {
    return p.sal
}

Three characteristics of object-oriented programming - inheritance

The need to look at a problem, leads inherited

A small problem, see a system of student test program extends01.go, ask questions reuse of code
1) fields and methods Pupil and the Graduate almost two structures, but we write the same code, not the code reusability
strong
2) appears redundant code, and the code is not conducive to maintenance, while not conducive to extended functions.
3) Solution - be solved by inheritance

package main

import (
    "fmt"
)




//编写一个学生考试系统

type Student struct {
    Name string
    Age int
    Score int
}

//将Pupil 和 Graduate 共有的方法也绑定到 *Student
func (stu *Student) ShowInfo() {
    fmt.Printf("学生名=%v 年龄=%v 成绩=%v\n", stu.Name, stu.Age, stu.Score)
}
func (stu *Student) SetScore(score int) {
    //业务判断
    stu.Score = score
}

//给 *Student 增加一个方法,那么 Pupil 和 Graduate都可以使用该方法
func (stu *Student) GetSum(n1 int, n2 int) int {
    return n1 + n2
}

//小学生
type Pupil struct { 
    Student //嵌入了Student匿名结构体
}

//显示他的成绩

//这时Pupil结构体特有的方法,保留
func (p *Pupil) testing() {
    fmt.Println("小学生正在考试中.....")
}

//大学生, 研究生。。


//大学生
type Graduate struct {
    Student //嵌入了Student匿名结构体
}

//显示他的成绩
//这时Graduate结构体特有的方法,保留
func (p *Graduate) testing() {
    fmt.Println("大学生正在考试中.....")
}

//代码冗余.. 高中生....

func main() {

    //当我们对结构体嵌入了匿名结构体使用方法会发生变化
    pupil := &Pupil{}
    pupil.Student.Name = "tom~"
    pupil.Student.Age = 8
    pupil.testing() 
    pupil.Student.SetScore(70)
    pupil.Student.ShowInfo()
    fmt.Println("res=", pupil.Student.GetSum(1, 2))


    graduate := &Graduate{}
    graduate.Student.Name = "mary~"
    graduate.Student.Age = 28
    graduate.testing() 
    graduate.Student.SetScore(90)
    graduate.Student.ShowInfo()
    fmt.Println("res=", graduate.Student.GetSum(10, 20))
}

Inheritance can be solved code reuse, so that our program closer to the human mind.
When there is a plurality of identical structure attributes (fields), and methods, the structure can be abstracted from these structures (such as just
Student), these same properties and methods defined in this structure.
Other structures without redefining these attributes (fields) and method, only a nested structure Student anonymous to
say: in Golang, if a nested struct another anonymous structure, then the structure body can directly access
ask fields and methods of anonymous structures, enabling the inheritance feature.

Anonymous nested structure of basic grammar

type Goods struct {
Name string
Price int
}
type Book struct {
Goods //这里就是嵌套匿名结构体 Goods
Writer string
}

Inheritance brings convenience to the programmer

Reusability 1) increases the code
2) scalability and maintainability of the code improves

In-depth discussion of inheritance

1) structure can use all fields and methods of anonymous nested structure, namely: the first letter in uppercase and lowercase fields, methods,
can be used. [Examples] Description
2) anonymous access field structure can be simplified

package main

import (
    "fmt"
)

type A struct {
    Name string
    age int
}

func (a *A) SayOk() {
    fmt.Println("A SayOk", a.Name)
}

func (a *A) hello() {
    fmt.Println("A hello", a.Name)
}

type B struct {
    A
    Name string 
}

func (b *B) SayOk() {
    fmt.Println("B SayOk", b.Name)
}

func main() {

    // var b B
    // b.A.Name = "tom"
    // b.A.age = 19
    // b.A.SayOk()
    // b.A.hello()

    // //上面的写法可以简化

    // b.Name = "smith"
    // b.age = 20
    // b.SayOk()
    // b.hello()

    var b B
    b.Name = "jack" // ok
    b.A.Name = "scott"
    b.age = 100  //ok
    b.SayOk()  // B SayOk  jack
    b.A.SayOk() //  A SayOk scott
    b.hello() //  A hello ? "jack" 还是 "scott"

}

The above summary of the code

(1) when we directly accessing a field or method b, which performs processes such as b.Name

(2) The compiler would read corresponding type b Name there, if so, a direct call type Name field B

(3) If you do not go to see B embedded in anonymous structure A has not declared the Name field, if you call, if not
continue to find .. If you can not find on the error.
3) When the structure and anonymous structures when the same field or method, the compiler uses the principle of accessing the nearest access, as desired to access
the fields and methods of anonymous structures can be distinguished by anonymous Examples illustrate the structure name]
4) embedded in the structure of two (or more ) anonymous structures, such as two anonymous structures have the same fields and methods (while the structure itself
is not the same name fields and methods), during a visit, you must explicitly specify the name of the anonymous structure, otherwise the compilation error. [Illustrates]
5) If a nested struct structure of a well-known, this model is the combination, if the combination is the relationship, then the combination of access
time field structure or method, it is necessary to bring the name structure
6) after anonymous nested structure, you can be created when the structure variables (example), which directly specifies the value of each field is anonymous structure
Description
1) If there is a structure of type int anonymous field, can not be the second.
2) If you need to have more int field, you must specify the name of the field to int

Object-oriented programming - multiple inheritance

Multiple inheritance described
as a plurality of nested struct anonymous structure, the structure may then directly access the anonymous nested structure field and square
method, thereby achieving multiple inheritance.
Multiple inheritance details Description
1) as anonymous structure fitted with the same name of the field or method, at the time of access, the structure needs to be anonymous type name
distinguished. [Presentation] Case
2) In order to ensure simplicity of the code, suggest that you try not to use multiple inheritance

package main
import (
    "fmt"
)

type A struct {
    Name string
    age int
}
type B struct {
    Name string
    Score float64
}
type C struct {
    A
    B
    //Name string
}

type D struct {
    a A //有名结构体
}


type Goods struct {
    Name string
    Price float64
}

type Brand struct {
    Name string
    Address string
}

type TV struct {
    Goods
    Brand   
}

type TV2 struct {
    *Goods
    *Brand  
}

type Monster struct  {
    Name string
    Age int
}

type E struct {
    Monster
    int
    n int
}

func main() {
    var c C
    //如果c 没有Name字段,而A 和 B有Name, 这时就必须通过指定匿名结构体名字来区分
    //所以 c.Name 就会包编译错误, 这个规则对方法也是一样的!
    c.A.Name = "tom" // error
    fmt.Println("c")

    //如果D 中是一个有名结构体,则访问有名结构体的字段时,就必须带上有名结构体的名字
    //比如 d.a.Name 
    var d D 
    d.a.Name = "jack"


    //嵌套匿名结构体后,也可以在创建结构体变量(实例)时,直接指定各个匿名结构体字段的值
    tv := TV{ Goods{"电视机001", 5000.99},  Brand{"海尔", "山东"}, }

    //演示访问Goods的Name
    fmt.Println(tv.Goods.Name)
    fmt.Println(tv.Price) 

    tv2 := TV{ 
        Goods{
            Price : 5000.99,
            Name : "电视机002", 
        },  
        Brand{
            Name : "夏普", 
            Address :"北京",
        }, 
    }

    fmt.Println("tv", tv)
    fmt.Println("tv2", tv2)

    tv3 := TV2{ &Goods{"电视机003", 7000.99},  &Brand{"创维", "河南"}, }

    tv4 := TV2{ 
            &Goods{
                Name : "电视机004", 
                Price : 9000.99,
            },  
            &Brand{
                Name : "长虹", 
                Address : "四川",
            }, 
        }

    fmt.Println("tv3", *tv3.Goods, *tv3.Brand)
    fmt.Println("tv4", *tv4.Goods, *tv4.Brand)


    //演示一下匿名字段时基本数据类型的使用
    var e E
    e.Name = "狐狸精"
    e.Age = 300
    e.int = 20
    e.n = 40
    fmt.Println("e=", e)

}

Interface (interface)

basic introduction

In order, we should learn multi-state, multi-state study but before, we need to explain the interface (interface), because in Golang polymorphic
properties primarily through the interface to be embodied.

Interface Quick Start

This design requirements Golang programming also will be a substantial presence, and I have said that a program is a world, in the real world
the presence of the community, will also appear in the program. We use to simulate the look of the previous scenarios.
Code

package main
import (
    "fmt"
)

//声明/定义一个接口
type Usb interface {
    //声明了两个没有实现的方法
    Start() 
    Stop()
}


//声明/定义一个接口
type Usb2 interface {
    //声明了两个没有实现的方法
    Start() 
    Stop()
    Test()
}



type Phone struct {

}  

//让Phone 实现 Usb接口的方法
func (p Phone) Start() {
    fmt.Println("手机开始工作。。。")
}
func (p Phone) Stop() {
    fmt.Println("手机停止工作。。。")
}

type Camera struct {

}
//让Camera 实现   Usb接口的方法
func (c Camera) Start() {
    fmt.Println("相机开始工作~~~。。。")
}
func (c Camera) Stop() {
    fmt.Println("相机停止工作。。。")
}


//计算机
type Computer struct {

}

//编写一个方法Working 方法,接收一个Usb接口类型变量
//只要是实现了 Usb接口 (所谓实现Usb接口,就是指实现了 Usb接口声明所有方法)
func (c Computer) Working(usb Usb) {

    //通过usb接口变量来调用Start和Stop方法
    usb.Start()
    usb.Stop()
}

func main() {

    //测试
    //先创建结构体变量
    computer := Computer{}
    phone := Phone{}
    camera := Camera{}

    //关键点
    computer.Working(phone)
    computer.Working(camera) //
}

Again that the concept of interfaces

interface type may define a set of methods, but these need not be implemented. And the interface can not contain any variable. To a
time-defined types (such as the structure Phone) to be used, depending on the circumstances in these methods to write (implemented).

Description
1) interfaces in all the methods have no method body, ie the interface methods are not implemented. Interface reflects the programming of
thought polymorphism and high cohesion and low coupling.
2) Golang in the interface, no explicit implementation. As long as a variable containing all methods of an interface type, then the
variable will implement this interface. Therefore, Golang no such keywords implement

Notes and detail
1) interface itself can not create an instance, but can point to a custom type implements the interface variable (instance)
2) All interface methods are no method bodies, namely the method is not implemented.
3) In Golang in a custom type requires an interface all methods are realized, we say that this custom type implements this interface.
4) a custom type only implements an interface to the instance of the custom type (variable) assigned to the interface type
5) as long as the custom data type, the interface can be implemented, not only the structure type.
6) a custom type can implement multiple interfaces
7) Golang interface can not have any variable
8) an interface (such as A interface) a plurality of other interfaces can inherit (such as B, C Interface), if the time to achieve A-interface , a method must B, C are all implemented interfaces.
. 9) interface type default is a pointer (reference type), if not used for interface initialization, the outputs nil
10) empty interface interface {} no way, all types implement the empty interface, i.e., we can any put a variable
is assigned to empty interface.

package main
import (
    "fmt"
)



type Stu struct {
    Name string
}

func (stu Stu) Say() {
    fmt.Println("Stu Say()")
}


type integer int

func (i integer) Say() {
    fmt.Println("integer Say i =" ,i )
}


type AInterface interface {
    Say()
}

type BInterface interface {
    Hello()
}
type Monster struct {

}
func (m Monster) Hello() {
    fmt.Println("Monster Hello()~~")
}

func (m Monster) Say() {
    fmt.Println("Monster Say()~~")
}

func main() {
    var stu Stu //结构体变量,实现了 Say() 实现了 AInterface
    var a AInterface = stu
    a.Say()


    var i integer = 10
    var b AInterface = i
    b.Say() // integer Say i = 10


    //Monster实现了AInterface 和 BInterface
    var monster Monster
    var a2 AInterface = monster
    var b2 BInterface = monster
    a2.Say()
    b2.Hello()
}
package main
import (
    "fmt"
)

type BInterface interface {
    test01()
}

type CInterface interface {
    test02()
}

type AInterface interface {
    BInterface
    CInterface
    test03()
}

//如果需要实现AInterface,就需要将BInterface CInterface的方法都实现
type Stu struct {
}
func (stu Stu) test01() {

}
func (stu Stu) test02() {
    
}
func (stu Stu) test03() {
    
}

type T  interface{

}

func main() {
    var stu Stu
    var a AInterface = stu
    a.test01()

    var t T = stu //ok
    fmt.Println(t)
    var t2 interface{}  = stu
    var num1 float64 = 8.8
    t2 = num1
    t = num1
    fmt.Println(t2, t)
}
package main
import "fmt"
type Usb interface {
    Say()
}
type Stu struct {
}
func (this *Stu) Say() {
    fmt.Println("Say()")
}
func main() {
    var stu Stu = Stu{}
    // 错误! 会报 Stu类型没有实现Usb接口 , 
    // 如果希望通过编译,  var u Usb = &stu
    var u Usb = stu  
    u.Say()
    fmt.Println("here", u)
}

    

Interface programming best practices

Hero implements sorting of slice structure: sort.Sort (data Interface)

package main
import (
    "fmt"
    "sort"
    "math/rand"
)

//1.声明Hero结构体
type  Hero struct{
    Name string
    Age int
}

//2.声明一个Hero结构体切片类型
type HeroSlice []Hero

//3.实现Interface 接口
func (hs HeroSlice) Len() int {
    return len(hs)
}

//Less方法就是决定你使用什么标准进行排序
//1. 按Hero的年龄从小到大排序!!
func (hs HeroSlice) Less(i, j int) bool {
    return hs[i].Age < hs[j].Age
    //修改成对Name排序
    //return hs[i].Name < hs[j].Name
}

func (hs HeroSlice) Swap(i, j int) {
    //交换
    // temp := hs[i]
    // hs[i] = hs[j]
    // hs[j] = temp
    //下面的一句话等价于三句话
    hs[i], hs[j] = hs[j], hs[i]
}


//1.声明Student结构体
type  Student struct{
    Name string
    Age int
    Score float64
}

//将Student的切片,安Score从大到小排序!!

func main() {

    //先定义一个数组/切片
    var intSlice = []int{0, -1, 10, 7, 90}
    //要求对 intSlice切片进行排序
    //1. 冒泡排序...
    //2. 也可以使用系统提供的方法 
    sort.Ints(intSlice) 
    fmt.Println(intSlice)

    //请大家对结构体切片进行排序
    //1. 冒泡排序...
    //2. 也可以使用系统提供的方法

    //测试看看我们是否可以对结构体切片进行排序
    var heroes HeroSlice
    for i := 0; i < 10 ; i++ {
        hero := Hero{
            Name : fmt.Sprintf("英雄|%d", rand.Intn(100)),
            Age : rand.Intn(100),
        }
        //将 hero append到 heroes切片
        heroes = append(heroes, hero)
    }

    //看看排序前的顺序
    for _ , v := range heroes {
        fmt.Println(v)
    }

    //调用sort.Sort
    sort.Sort(heroes)
    fmt.Println("-----------排序后------------")
    //看看排序后的顺序
    for _ , v := range heroes {
        fmt.Println(v)
    }

    i := 10
    j := 20
    i, j = j, i
    fmt.Println("i=", i, "j=", j) // i=20 j = 10
}

Implement an interface vs inheritance

We might implement interfaces and inherit more confused, then they really have what difference does it

package main
import (
    "fmt"
)

//Monkey结构体
type Monkey struct {
    Name string
}

//声明接口
type BirdAble interface {
    Flying()
}

type FishAble interface {
    Swimming()
}

func (this *Monkey) climbing() {
    fmt.Println(this.Name, " 生来会爬树..")
}

//LittleMonkey结构体
type LittleMonkey struct {
    Monkey //继承
}


//让LittleMonkey实现BirdAble
func (this *LittleMonkey) Flying() {
    fmt.Println(this.Name, " 通过学习,会飞翔...")
}

//让LittleMonkey实现FishAble
func (this *LittleMonkey) Swimming() {
    fmt.Println(this.Name, " 通过学习,会游泳..")
}

func main() {

    //创建一个LittleMonkey 实例
    monkey := LittleMonkey{
        Monkey {
            Name : "悟空",
        },
    }
    monkey.climbing()
    monkey.Flying()
    monkey.Swimming()

}

1) When A structure inherits the B structure, then A structure automatically inherited fields and methods of B structure, and can be directly
connected using
2) When A structure required extensions, while undesirable to destroy inheritance , it is possible to implement an interface can be, so we can consider: implementation of the interface complements the inheritance mechanism that implements the interface can be seen as a supplement to the inheritance

Different interfaces and inheritance to solve the problem
inherited value mainly due to: solve the reusability and maintainability of the code.
The main value lies in the interface: design, design a good variety of specifications (method), so that other custom type to implement these methods.
The interface is more flexible than inherited Person Student BirdAble LittleMonkey
inherit the interface is more flexible than inheritance is to meet is - a relationship, and the interface just meet like - of a relationship.
Interface code is decoupled to some extent

OOP - Polymorphism

basic introduction

Variant (examples) have a variety of forms. The third object-oriented features, in Go, characterized by polymorphic interface implementation. You can follow a unified interface to invoke different implementations. At this interface variables to present different forms.
Getting started
in front of Usb Interface case, Usb usb, both phones can receive variables, and variables can receive a camera, a manifestation of Usb Interface polymorphism characteristics.

Interface embodied in two forms of polymorphism

Polymorphic parameters

In the previous case the interface Usb, Usb usb, that is, the phone can receive variables, and variables can receive a camera, a manifestation of Usb connection polymorphism.
Polymorphic array
demonstrate a case: Usb to the array, and the structure Camera Phone storage structure variables
Remarks:

package main
import (
    "fmt"
)

//声明/定义一个接口
type Usb interface {
    //声明了两个没有实现的方法
    Start()
    Stop()
}

type Phone struct {
    name string
}  

//让Phone 实现 Usb接口的方法
func (p Phone) Start() {
    fmt.Println("手机开始工作。。。")
}
func (p Phone) Stop() {
    fmt.Println("手机停止工作。。。")
}


type Camera struct {
    name string
}
//让Camera 实现   Usb接口的方法
func (c Camera) Start() {
    fmt.Println("相机开始工作。。。")
}
func (c Camera) Stop() {
    fmt.Println("相机停止工作。。。")
}



func main() {
    //定义一个Usb接口数组,可以存放Phone和Camera的结构体变量
    //这里就体现出多态数组
    var usbArr [3]Usb
    usbArr[0] = Phone{"vivo"}
    usbArr[1] = Phone{"小米"}
    usbArr[2] = Camera{"尼康"}
    
    fmt.Println(usbArr)

}

Type assertion

Of a specific needs, the type assertion leads
basic introduction
type assertion, since the interface is a general type, do not know the specific type, if you want to turn to a specific type, it is necessary to use type assertions,
specifically as follows:

package main
import (
    "fmt"
)
type Point struct {
    x int
    y int
}
func main() {
    var a interface{}
    var point Point = Point{1, 2}
    a = point  //oK
    // 如何将 a 赋给一个Point变量?
    var b Point
    // b = a 不可以
    // b = a.(Point) // 可以
    b = a.(Point) 
    fmt.Println(b) // 


    //类型断言的其它案例
    // var x interface{}
    // var b2 float32 = 1.1
    // x = b2  //空接口,可以接收任意类型
    // // x=>float32 [使用类型断言]
    // y := x.(float32)
    // fmt.Printf("y 的类型是 %T 值是=%v", y, y)


    //类型断言(带检测的)
    var x interface{}
    var b2 float32 = 2.1
    x = b2  //空接口,可以接收任意类型
    // x=>float32 [使用类型断言]

    //类型断言(带检测的)
    if y, ok := x.(float32); ok {
        fmt.Println("convert success")
        fmt.Printf("y 的类型是 %T 值是=%v", y, y)
    } else {
        fmt.Println("convert fail")
    }
    fmt.Println("继续执行...")

}

Description of the above code:
During type of assertion, if the types do not match, it will report panic, and therefore the type assertion, to ensure that the original empty interface
type is the assertion of points.
How making assertions, bring detection mechanism, if successful ok, otherwise do not panic reported

Best Practices type of assertion 1

In the foregoing case Usb interface to make improvements:
to add a specific structure Phone method call (), when the interface receives Usb Phone is variable, call also need to call
the method, take the code:

package main
import (
    "fmt"
)

//声明/定义一个接口
type Usb interface {
    //声明了两个没有实现的方法
    Start()
    Stop()
}

type Phone struct {
    name string
}  

//让Phone 实现 Usb接口的方法
func (p Phone) Start() {
    fmt.Println("手机开始工作。。。")
}
func (p Phone) Stop() {
    fmt.Println("手机停止工作。。。")
}

func (p Phone) Call() {
    fmt.Println("手机 在打电话..")
}


type Camera struct {
    name string
}
//让Camera 实现   Usb接口的方法
func (c Camera) Start() {
    fmt.Println("相机开始工作。。。")
}
func (c Camera) Stop() {
    fmt.Println("相机停止工作。。。")
}

type Computer struct {

}

func (computer Computer) Working(usb Usb) {
    usb.Start()
    //如果usb是指向Phone结构体变量,则还需要调用Call方法
    //类型断言..[注意体会!!!]
    if phone, ok := usb.(Phone); ok {
        phone.Call()
    }
    usb.Stop()
}

func main() {
    //定义一个Usb接口数组,可以存放Phone和Camera的结构体变量
    //这里就体现出多态数组
    var usbArr [3]Usb
    usbArr[0] = Phone{"vivo"}
    usbArr[1] = Phone{"小米"}
    usbArr[2] = Camera{"尼康"}

    //遍历usbArr
    //Phone还有一个特有的方法call(),请遍历Usb数组,如果是Phone变量,
    //除了调用Usb 接口声明的方法外,还需要调用Phone 特有方法 call. =》类型断言
    var computer Computer
    for _, v := range usbArr{
        computer.Working(v)
        fmt.Println()
    }
    //fmt.Println(usbArr)
}

 Best Practices type of assertion 2

Write a function, circulation determine the type of arguments passed:

package main
import (
    "fmt"
)


//定义Student类型
type Student struct {

}

//编写一个函数,可以判断输入的参数是什么类型
func TypeJudge(items... interface{}) {
    for index, x := range items {
        switch x.(type) {
            case bool :
                fmt.Printf("第%v个参数是 bool 类型,值是%v\n", index, x)
            case float32 :
                fmt.Printf("第%v个参数是 float32 类型,值是%v\n", index, x)
            case float64 :
                fmt.Printf("第%v个参数是 float64 类型,值是%v\n", index, x)
            case int, int32, int64 :
                fmt.Printf("第%v个参数是 整数 类型,值是%v\n", index, x)
            case string :
                fmt.Printf("第%v个参数是 string 类型,值是%v\n", index, x)
            case Student :
                fmt.Printf("第%v个参数是 Student 类型,值是%v\n", index, x)
            case *Student :
                fmt.Printf("第%v个参数是 *Student 类型,值是%v\n", index, x)
            default :
                fmt.Printf("第%v个参数是  类型 不确定,值是%v\n", index, x)
        }
    }
}

func main() {

    var n1 float32 = 1.1
    var n2 float64 = 2.3
    var n3 int32 = 30
    var name string = "tom"
    address := "北京"
    n4 := 300

    stu1 := Student{}
    stu2 := &Student{}

    TypeJudge(n1, n2, n3, name, address, n4, stu1, stu2)


}

go Object-Oriented finally finished ( ^ ▽ ^ )! ~ ~ ~ ~

Guess you like

Origin www.cnblogs.com/ygjzs/p/11874869.html