Bootstrap

【GO 编程语言】面向对象

指针与结构体



在这里插入图片描述


一、OOP 思想

Go语言不是面向对象的语言,这里只是通过一些方法来模拟面向对象,从而更好的来理解面向对象思想

  • 面向过程的思维模式
    • 1.面向过程的思维模式是简单的线性思维,思考问题首先陷入第一步做什么、第二步做什么的细节中,这种思维模式适合处埋简单的事情。
    • 2.面向对象的思维模式说白了就是分类思维模式。首先思考解决问题,需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
  • 面向对象的三大特点:封装、继承、多态

二、继承

继承就是子类继承父类的特征和行为,使得子类具有父类的属性和方法,使得子类具有父类相同的行为。子类会具有父类的一般特性也会具有自身的特性。

Go 使用结构体嵌套实现继承

package main

import "fmt"

// 1、定义一个父“类”结构体
type Person struct {
	name string
	age  int
}

// 2、定义一个子“类”结构体
type Student struct {
	Person        // 匿名变量、继承
	school string // 子类自己的属性字段
}

func main() {

	g1 := Person{name: "guan", age: 18}
	fmt.Println(g1.name)

	g2 := Student{Person{name: "guan0001", age: 22}, school: "NNU"}
	fmt.Println(g2.Person.name)
	fmt.Println(g2.name)
	// 提升字段
	// 对于Student来说,Person是匿名字段,Person中的属性 name、age就叫做提升字段
	// 提升字段可以通过名字直接访问不需要通过结构体名Person
	var g3 Student
	g3.name = "guan003"
	g3.school = "NNU"
	fmt.Println(g3)
}

三、方法

什么事方法

Go 语言中同时拥有函数和方法。

  • 方法:

    • 某个类别的行为功能,需要制定的接受者调用
    • 一段独立的功能代码,可以直接调用
  • 函数

    • 一段独立功能的代码,可以直接调用
    • 命名不能冲突
package main
import "fmt"
type Dog struct {
	name string
	age  int
}
type Cat struct {
	name string
	age  int
}

// 方法定义
func (dog Dog) eat() {
	fmt.Println("Dog,eating")
}
func (dog Dog) sleep() {
	fmt.Println("Dog,sleeping")
}
func (cat Cat) eat() {
	fmt.Println("Cat,eating")
}
func main() {
	dog := Dog{name: "wangwangDog", age: 1}
	dog.eat()
	dog.sleep()
	cat := Cat{name: "miaomiaoCat", age: 2}
	cat.eat()

}

在这里插入图片描述# 方法重写

  • 子类可以重写父类的方法 override
  • 子类可以新增自己的属性和方法
  • 子类可以直接访问父类的属性和方法
package main

import (
	"fmt"
)

type Animal struct {
	name string
	age  int
}
type Dog struct {
	Animal
}
type Cat struct {
	Animal
	color string
}

// 方法定义
func (animal Animal) eat() {
	fmt.Println(animal.name, "eating")
}
func (animal Animal) sleep() {
	fmt.Println(animal.name, "sleeping")
}
// 子类重写父类的方法
func (cat Cat) eat() {
	fmt.Println(cat.name, "eating")
}
// 子类拓展自己的方法
func (cat Cat) miao() {
	fmt.Println(cat.name, "miao")
}
func main() {
	dog := Dog{Animal{name: "wangwangDog", age: 1}}
	dog.eat()
	dog.sleep()
	cat := Cat{Animal{name: "miaomiaoCat", age: 2}, "red"}
	cat.eat()
	cat.miao()

}

在这里插入图片描述

四、接口实现

Go语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现接口定义的全部方法就是实现了这个接口。

package main

import "fmt"

// USB 通过 interface 来声明定义一个接口
type USB interface {
	Input()
	Output()
}
type Mouse struct {
	name string
}

// go 语言不需要像java通过implement显示的实现接口
// 实现接口中的方法,就算实现了接口
// go语言中,接口和实现类的关系,是非侵入式的
func (mouse Mouse) Input() {
	fmt.Println(mouse.name, "鼠标输入")
}
func (mouse Mouse) Output() {
	fmt.Println(mouse.name, "鼠标输出")
}

func test(u USB) {
	u.Input()
	u.Output()
}

func main() {
	// 通过传入接口实现类来进行具体方法的调用
	m := Mouse{name: "logi"}
	test(m)
}

在这里插入图片描述

五、多态

多态:一个事务拥有多种形态。是面向对象中很重要的一个特点。

Go 语言通过接口来模拟多态

package main

import (
	"fmt"
)

type Animal interface {
	eat()
	sleep()
}
type Dog struct {
	name string
}
type Cat struct {
	name string
}

func (cat Cat) sleep() {
	//TODO implement me
	fmt.Println(cat.name, "sleeping")
}

// 方法定义
func (dog Dog) eat() {
	fmt.Println(dog.name, "eating")
}
func (dog Dog) sleep() {
	fmt.Println(dog.name, "sleeping")
}

func (cat Cat) eat() {
	fmt.Println(cat.name, "eating")
}

func (cat Cat) miao() {
	fmt.Println(cat.name, "miao")
}

func animalTest(a Animal) {
	fmt.Println("animalTest")
	a.eat()
	a.sleep()
}
func main() {
	dog := Dog{name: "旺财"}
	dog.eat()
	dog.sleep()
	cat := Cat{name: "喵喵"}
	cat.eat()
	cat.sleep()
	cat.miao()

	// animal
	animalTest(dog)
	animalTest(cat)
	// 定义一个类型为接口类型的变量
	// 实际上可以赋值为任意实现类的对象
	var animal Animal
	animal = dog
	fmt.Println(animal)
	animal = cat
	fmt.Println(cat)
}

在这里插入图片描述

六、空接口

package main

import (
	"fmt"
)

// 空接口
type Animal interface {
}
type Dog struct {
	name string
}
type Cat struct {
	name string
}

func (cat Cat) sleep() {
	//TODO implement me
	fmt.Println(cat.name, "sleeping")
}

// 方法定义
func (dog Dog) eat() {
	fmt.Println(dog.name, "eating")
}
func (dog Dog) sleep() {
	fmt.Println(dog.name, "sleeping")
}

func (cat Cat) eat() {
	fmt.Println(cat.name, "eating")
}

func (cat Cat) miao() {
	fmt.Println(cat.name, "miao")
}

func test(a Animal) {
	fmt.Println(a)
}

// fmt 下的输出接受的参数都是这样的
func test1(a Animal) {
	fmt.Println(a)
}

func main() {

	var animal1 Animal = Dog{name: "旺财"}
	fmt.Println(animal1)

	var animal2 Animal = Cat{name: "喵喵"}
	fmt.Println(animal2)

	var animal3 Animal = "hello"
	fmt.Println(animal3)

	var animal4 Animal = 666
	fmt.Println(animal4)
	fmt.Println("--------------------------")

	test(animal1)
	test(animal2)
	test(animal3)
	test(animal4)
	fmt.Println("--------------------------")

	test1(animal1)
	test1(animal2)
	test1(animal3)
	test1(animal4)

	// map key string value obj
	map1 := make(map[string]interface{})
	map1["name"] = "guan12319"
	map1["age"] = 18
	map1["dog"] = Dog{name: "土狗"}
	fmt.Println("--------------------------")
	// 切片
	s1 := make([]interface{}, 0, 10)
	s1 = append(s1, animal1, animal2, animal3, animal4, 666, 888)
	fmt.Println(s1)
	fmt.Println(map1)
}

在这里插入图片描述

七、接口继承

package main

import "fmt"

// 接口继承
type A interface {
	test01()
}

type B interface {
	test02()
}

type C interface {
	A
	B
	test03()
}

type Dog struct {
}

func (dog Dog) test01() {
	fmt.Println("test01")
}
func (dog Dog) test02() {
	fmt.Println("test02")
}
func (dog Dog) test03() {
	fmt.Println("test03")
}

func main() {
	var dog Dog = Dog{}
	dog.test01()
	dog.test02()
	dog.test03()

	// 在接口嵌套中,嵌套的接口默认继承了被嵌套接口的所有方法
	var testA A = dog
	testA.test01()
	var testB B = dog
	testB.test02()
	var testC C = dog
	testC.test01()
	testC.test02()
	testC.test03()
}

在这里插入图片描述

八、接口断言

package main

import "fmt"

// 接口断言
func assertString(i interface{}) {
	s := i.(string)
	fmt.Println(s)
}
func assertInt(i interface{}) {
	s, ok := i.(int)
	if ok {
		fmt.Println("接口变量i是int类型,i=", s)

	} else {
		fmt.Println("接口变量i不是int类型")
	}

}

type T interface {
}

func test(i interface{}) {
	switch i.(type) {
	// 如果断言的类型,同时实现了Switch断言的多个case,取第一个case
	case string:
		fmt.Println("string类型")

	case int:
		fmt.Println("int类型")
	case T:
		fmt.Println("T类型")
	case nil:
		fmt.Println("nil类型")
	default:
		fmt.Println("未知类型")
	}
}
func main() {
	assertString("test")
	assertInt(666)
	a := "hello"
	b := 888
	c := true
	var i T
	test(a)
	test(b)
	test(c)
	test(i)
}

在这里插入图片描述

九、Type别名

package main

import "fmt"

// 通过type 关键字的定义,DiyInt就是一种新的类型,它具有int的特性
type Diyint int

func main() {
	var a Diyint = 88
	var b int = 66
	c := int(a) + b
	fmt.Println(c)
	// myint类型只会在代码中存在,编译完成时并不会有myint类型
	type myint = int
	var d myint = 66
	var e int = 99
	f := d + e
	fmt.Println(f)
}

在这里插入图片描述

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;