GoLang 面向对象

Golang Series

Hello GoLang: https://blog.yexca.net/archives/154
GoLang (var and const) 变量与常量: https://blog.yexca.net/archives/155
GoLang (func) 函数: https://blog.yexca.net/archives/156
GoLang (slice and map) 切片: https://blog.yexca.net/archives/160
GoLang (OOP) 面向对象: 本文
GoLang (reflect) 反射: https://blog.yexca.net/archives/204
GoLang (struct tag) 结构体标签: https://blog.yexca.net/archives/205
GoLang (goroutine) go 程: https://blog.yexca.net/archives/206
GoLang (channel) 通道: https://blog.yexca.net/archives/207


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

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

struct

首先是自定义类型,使用 type 关键字,类似于 C

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

package main

import "fmt"

type Person struct {
    name string
    age  int
}

fun     main() {
    var zhang Person
    zhang.name = "zhangSan"
    zhang.age = 20

    fmt.Print(zhang)
}

函数传递相关,不使用指针是值传递

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)
}

封装

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),属性名也是同理

继承

以下代码处于同一文件,父类

// 父类
type Person struct {
    name string
    age  int
}

// 父类的方法
func (this *Person) Eat() {
    fmt.Println("Person Eat...")
}
func (this *Person) Walk() {
    fmt.Println("Person Walk...")
}

子类

// 子类
type SuperMan struct {
    Person     // 继承父类
    level  int // 子类属性
}

// 子类重写父类方法
func (this *SuperMan) Walk() {
    fmt.Println("SuperMan Walk")
}
// 子类特有方法
func (this *SuperMan) Fly() {}
    

main 函数

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

多态

以下代码处于同一文件,定义接口

// 接口,本质是一个指针
type Animal interface {
    Sleep()
    GetName() string
    GetType() string
}

实现类一

// 实现类一
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
}

实现类二

// 实现类二
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

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)

}

万能类型与断言

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-NC-SA 4.0 by the author.
最后更新于 2025-01-28 20:17 +0900