Home GoLand 面向对象
Post
Cancel

GoLand 面向对象

通过使用结构体构建类与对象的概念

了解面向对象:面向对象基础

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
 */
This post is licensed under CC BY 4.0 by the author.

注册中心 - Eureka

CSS 选择器