通过使用结构体构建类与对象的概念
了解面向对象:面向对象基础
struct
首先是自定义类型,使用 type 关键字,类似于 C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package main
import "fmt"
type myType int
func main() {
var a myType
fmt.Println("a =", a)
fmt.Printf("type of a is %T", a)
}
/*
* 输出
* a = 0
* type of a is main.myTye
*/
定义类型使用 stuct
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main
import "fmt"
type Person struct {
name string
age int
}
func main() {
var zhang Person
zhang.name = "zhangSan"
zhang.age = 20
fmt.Print(zhang)
}
函数传递相关,不使用指针是值传递
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package main
import "fmt"
type Person struct {
name string
age int
}
// 值传递,不会修改原数据
func changeName(person Person) {
person.name = "liSi"
}
// 引用传递,会修改原数据
func changeAge(person *Person) {
person.age = 18
}
func main() {
var zhang Person
zhang.name = "zhangSan"
zhang.age = 20
fmt.Println(zhang)
changeName(zhang)
fmt.Println(zhang)
changeAge(&zhang)
fmt.Println(zhang)
}
封装
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main
import "fmt"
// 类
type Person struct {
// 属性
name string
age int
}
// 类的方法
func (this *Person) SetName(name string) {
this.name = name
}
func (this *Person) SetAge(age int) {
this.age = age
}
func (this *Person) GetName() string {
return this.name
}
func (this *Person) GetAge() int {
return this.age
}
func main() {
person := Person{name: "zhangSan", age: 18}
fmt.Println(person)
}
注意到上述 类名、方法名 首字母为大写,代表该类、方法可以被其他包访问 (java public),若首字母小写则只能此包访问 (java private),属性名也是同理
继承
以下代码处于同一文件,父类
1
2
3
4
5
6
7
8
9
10
11
12
13
// 父类
type Person struct {
name string
age int
}
// 父类的方法
func (this *Person) Eat() {
fmt.Println("Person Eat...")
}
func (this *Person) Walk() {
fmt.Println("Person Walk...")
}
子类
1
2
3
4
5
6
7
8
9
10
11
12
13
// 子类
type SuperMan struct {
Person // 继承父类
level int // 子类属性
}
// 子类重写父类方法
func (this *SuperMan) Walk() {
fmt.Println("SuperMan Walk")
}
// 子类特有方法
func (this *SuperMan) Fly() {
main 函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func main() {
// 定义子类属性,方式一
superMan1 := SuperMan{Person{"zhangSan", 18}, 4}
// 定义子类属性,方式二
var superMan2 SuperMan
superMan2.name = "liSi" // 因为同一个包,可以访问父类属性
superMan2.age = 20
superMan2.level = 5
// 子类调用父类方法
superMan1.Eat()
// 子类重写方法
superMan1.Walk()
// 子类方法
superMan2.Fly()
}
多态
以下代码处于同一文件,定义接口
1
2
3
4
5
6
// 接口,本质是一个指针
type Animal interface {
Sleep()
GetName() string
GetType() string
}
实现类一
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 实现类一
type Cat struct {
name string
kind string
}
// 实现接口所有方法
func (this *Cat) Sleep() {
fmt.Println("Cat Sleep()")
}
func (this *Cat) GetName() string {
return this.name
}
func (this *Cat) GetType() string {
return this.kind
}
实现类二
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 实现类二
type Dog struct {
name string
kind string
}
// 实现接口所有方法
func (this *Dog) Sleep() {
fmt.Println("Cat Sleep()")
}
func (this *Dog) GetName() string {
return this.name
}
func (this *Dog) GetType() string {
return this.kind
}
func ShowAnimal(animal Animal) {
fmt.Println(animal)
}
main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
func ShowAnimal(animal Animal) {
fmt.Println(animal)
}
func main() {
var animal Animal
animal = &Cat{"cat1", "cat"}
animal.Sleep()
animal = &Dog{"dog1", "dog"}
animal.Sleep()
cat := Cat{"cat2", "cat"}
dog := Dog{"dog2", "dog"}
ShowAnimal(&cat)
ShowAnimal(&dog)
}
万能类型与断言
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package main
import "fmt"
// 使用空接口表示万能数据类型
func f(arg interface{}) {
// 类型断言机制(即类型转换)
value, flag := arg.(string)
if !flag {
fmt.Println("arg is not string type")
} else {
fmt.Println("arg is string type, arg =", value)
}
}
func main() {
// 可以传入任意数据类型,包括自定
f("abc")
f(123)
f(3.14)
}
/*
* 输出
* arg is string type, arg = abc
* arg is not string type
* arg is not string type
*/