Article directory
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)
}
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)
}
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)
}
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)
}
}
}
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()
}
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