go语言入门十 | 青训营笔记

53 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 12 天

总结

面对对象的编程步骤:

  1. 声明结构体,确定结构体名
  2. 编写结构体字段
  3. 编写结构体方法
  1. 结构体的补充:

    1. Golang在创建结构体时候,可以直接指定字段值

      1. 在创建结构体变量时,把字段名和字段值写在一起, 这种写法,就不依赖字段的定义顺序,但是没有写字段名,就必须安装顺序来

        **var stu3 = Stu{
        		Name :"jack",
        		Age : 20,
        	}
        stu4 := Stu{
        	Age : 30,
        	Name : "mary",
        }**
        
      2. 创建结构体指针变量时,把字段名和字段值写在一起, 这种写法,就不依赖字段的定义顺序,但是没有写字段名,就必须安装顺序来

        **var stu7 = &Stu{
        	Name : "小李",
        	Age :49,
        }
        stu8 := &Stu{
        	Age :59,
        	Name : "小李~",
        }**
        
    2. 同一结构体不同变量的值互不干扰

  2. 工厂模式:类似Java中的封装

    1. 抽象:面对对象的思想可以简化为一种抽象的模型,把一类事物的共有属性(字段)和方法提取出来,形成一个物理模型(模板)
    2. 封装:把抽象出的字段和对字段的操作,封装在一起,数据保存在内部
    **package model
    import "fmt"
    
    type person struct {     //小写,不能访问person
    	Name string
    	age int   			//其它包不能直接访问..
    	sal float64
    }
    
    //1.写一个工厂模式的函数,相当于构造函数  -- 访问person
    func NewPerson(name string) *person {
        /*if....*/
    	return &person{
    		Name : name,
    	}
    }
    
    //2.为了访问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
    }**
    
    **package main
    import (
    	"fmt"
    	"/c/golang/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()) //年龄需要用到方法
    }**
    
  3. 继承:通过了匿名结构体来实现了继承特性。

    **type Good struct{
    	Name string
    	Price int
    }
    type Book struct{
    	Goods //这里就是嵌套匿名结构体Goods
    	Writer string
    }**
    
    **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
    }
    func main(){
        var b B
        b.A.Name = "tom"
        b.A.age = 19
        b.A.Sayok()
        b.A.hello()
        fmt.Println(b)
    }**
    
    1. 私有的可以继承使用,而且方法hello和Sayok方法无论是私有的还是公有的都可以直接使用,首字母大写或者小写均可以

    2. 在编译的时候可以把A去掉,进行简化,编译器也可以识别(编译器会自己找):自动寻找

          **var b B
          b.Name = "tom"
          b.age = 19
          b.Sayok()
          b.hello()**
      
    3. 当匿名结构体和结构体中的变量重复时候,编译器会采用就近原则:先自身再父类

    4. 结构体嵌入了两个或者多个匿名结构体,如果两个匿名结构体有相同的字段和方法(同时结构体本身没有相同的字段和方法),在访问时,就必须要指定匿名结构体的名字,否则编译会报错:自身找不到,父类有同名,报错

      这种情况也被称为多重继承,为了保证代码简洁性,建议尽量不使用多重继承。

    5. 嵌套匿名结构体后,可以在创建结构变量时,直接指定各个匿名结构体字段的值

      	**c := C{
              B{"张三",1000},
              A{"李四",19},
          }
      //,不可缺少**
      
    6. 结构体中可以只写类型

      **package main
      import "fmt"
      type A struct{
      	Name string    //相同字段
      	age int
      }
      type C struct{
      	A
      	int   //表示的是匿名字段
      }
      /*使用int方法*/
      func main(){
          var c C
          c.Name = "lihua"
          c.age = 100
          c.int = 20
          fmt.Println("int=",c.int)
          fmt.Println("c= ",c)
      }**