Golang learning path 5-use of structure/class encapsulation, etc.


Preface

Go language supports class operations, but there is no class keyword. Use struct to simulate classes and structures. Classes support encapsulation, bound methods, inheritance, etc.


1. Structure

A struct is an entity aggregated from zero or more values ​​of any type, which can be used to group data into a unit rather than each of them as a separate value.

1. Declare the structure

Use the keywords type and struct to define structures.

type StructName struct{
    
    
    FieldName type
}

2.Anonymous structure

You can declare a structure without creating a new data type and assign values ​​directly to variables.

func main() {
    
    
	ppl := struct {
    
    
		name   string
		age    int
		gender string
		score  float64
	}{
    
    }
	fmt.Println(ppl.name)
	ppl.name = "ppl"
	fmt.Println(ppl.name)
}

Complete code

package main

import "fmt"

type Student struct {
    
    
	// 定义结构体
	name   string
	age    int
	gender string
	score  float64
}

func main() {
    
    
	// 所有字段都写完整值value,可不写key
	ppl := Student{
    
    
		"ppl",
		18,
		"男",
		60.5, // 最后一字段写上逗号,不然花括号}要同一行
	}
	// 修改值
	ppl.name = "我的新名字哈哈哈"
	fmt.Println(ppl)
	// 部分字段有值时,需要写上:key:value,无值的默认为空值
	ppl1 := Student{
    
    
		name:  "PPL",
		score: 060.6,
	}
	fmt.Println(ppl1, "age:", ppl1.age, " gender:", ppl1.gender)
	prt := &ppl1 // 指针
	fmt.Println(prt.name)
	fmt.Println((*prt).name)

	// 匿名结构体
	ppl2 := struct {
    
    
		name   string
		age    int
		gender string
		score  float64
	}{
    
    }
	fmt.Println(ppl2.name)
	ppl2.name = "ppl"
	fmt.Println(ppl2.name)
}

Insert image description here


2. Category

1. Encapsulation and binding

The following structure simulates a class, has attributes, and is bound to the Eat method

type Person struct {
    
    
	// 成员属性
	name   string
	age    int
	gender string
	score  float64
}

// 类绑定方法,绑定后可使用成员属性
func (p Person) Eat() {
    
    
	p.name = "gsxl"
	fmt.Println("不使用指针 Eat func 修改为:", p.name)
}

Note the difference between using pointers and not using pointers:

  • No pointer modification is used: only the current member properties will be changed, and the original properties will not be changed.
  • Using pointer modification, the original attribute is also changed

Complete code

package main

import "fmt"

type Person struct {
    
    
	// 成员属性
	name   string
	age    int
	gender string
	score  float64
}

// 类绑定方法,绑定后可使用成员属性
func (p Person) Eat() {
    
    
	p.name = "gsxl"
	fmt.Println("不使用指针 Eat func 修改为:", p.name)
}

func (p *Person) Work() {
    
    
	p.name = "广深小龙"
	fmt.Println("使用指针 Work func 修改为:", p.name)
}

func main() {
    
    
	ppl := Person{
    
    
		name:   "ppl",
		age:    18,
		gender: "男",
		score:  66.23,
	}
	// 不使用指针修改:只会改变当前成员属性,原始属性不会改变
	ppl.Eat()
	fmt.Println(ppl.name)

	// 使用指针修改,原始属性也跟着改变
	ppl.Work()
	fmt.Println(ppl.name)
}

Insert image description here

2.Inheritance

1. For class inheritance, directly write the superclass name

type Human struct {
    
    
	// 超类/父类
	name   string
	age    int
	gender string
}

type Teacher struct {
    
    
	Human // 继承,直接写超类
	school string
	gender int
}

2. If this is the case, it is not considered inheritance, but nesting

type Human struct {
    
    
	// 超类/父类
	name   string
	age    int
	gender string
}

type Teacher struct {
    
    
	h      Human // 继承,直接写超类
	school string
	gender int
}

Complete code

package main

import "fmt"

type Human struct {
    
    
	// 超类/父类
	name   string
	age    int
	gender string
}

func (h *Human) Eat() {
    
    
	fmt.Println("Eat func:", h.name)
}

type Student1 struct {
    
    
	// 并非继承,只是嵌套类
	h      Human
	school string
}

type Teacher struct {
    
    
	Human // 继承,直接写超类
	school string
	gender int
}

func main() {
    
    
	s := Student1{
    
    
		h: Human{
    
    
			name:   "ppl",
			age:    25,
			gender: "男",
		},
		school: "广西大学",
	}
	s.h.Eat() // 嵌套调用

	t := Teacher{
    
    }
	t.name = "漂漂亮"
	fmt.Println(t.name)
	t.Eat() // 继承调用,我们在Teacher并没有创建Eat方法,但是被继承了默认创建了同名方法及属性

	// 定义了相同的属性,只能调用自己的,如果想调用父类那么需要.父类.属性
	fmt.Println("子类的gender:", t.gender)
	fmt.Println("父类的gender:", t.Human.gender)
}

Insert image description here

3. Polymorphism and interfaces

Before learning polymorphism, let's first understand the interface, which supports any type.
1. The interface
interface type is an abstract type. Usually used to receive parameters of any type, as follows:

/*
	1.关键字定义接口:interface
	2.interface接收任意数据类型
*/
func checkType(values ...interface{
    
    }) {
    
    
	for _, value := range values {
    
    
		switch v := value.(type) {
    
    
		case string:
			fmt.Println("this type is string:", v)
		case int:
			fmt.Println("this type is int:", v)
		case bool:
			fmt.Println("this type is bool:", v)
		default:
			fmt.Println("this type is default:", v)
		}
	}
}

Insert image description here
2. Polymorphism
Polymorphism can be understood: passing in different objects, calling the same method, and achieving different effects.
Here's an example: cats and dogs are both animals that need to eat food, so Eat() is called in the interface, cats and dogs both have Eat() methods, but the food is different, so the corresponding Eat is performed according to different objects ().

package main
import "fmt"
/*
多态:传入不同对象,调用相同方法,实现不同效果
1.定义一个接口,设计好需要调用接口,可多个
2.任何实现了此接口,都可赋值,从而实现多态
*/

type Animal interface {
    
    
	// 定义一个接口,接口可以多个函数,不可有实现
	Eat()
}

type Dog struct {
    
    
	name string
	eat  string
}

type Cat struct {
    
    
	name string
	eat  string
}

func (d *Dog) Eat() {
    
    
	fmt.Println("this is Dog eat", d.eat)
}

func (c *Cat) Eat() {
    
    
	fmt.Println("this is Cat eat", c.eat)
}

func main() {
    
    
	// 定义一个接口类变量
	var eat Animal
	
	// 动物狗
	dog := Dog{
    
    
		name: "小狗钱钱",
		eat:  "狗粮",
	}
	eat = &dog
	eat.Eat()

	// 动物猫
	cat := Cat{
    
    
		name: "招财猫",
		eat:  "猫粮",
	}
	eat = &cat
	eat.Eat()
}

Insert image description here

4. Class access rights

The go language follows the following rules:

  • public: the first letter is capitalized (both internal and external)
  • private: the first letter is lowercase (can only be called internally, cannot be called by someone other than your own package)

Summarize

Why do you think that a structure is a class and a class is a structure? It's normal if you also have this kind of doubt, because the preface mentioned that using structures to simulate classes realizes the three major characteristics of classes.
End

Guess you like

Origin blog.csdn.net/qq_42675140/article/details/127701129