【Go语言】面向对象编程

一、面向对象编程概念

面向过程编程

  • 整个过程分为若干步
  • 每一步对应一个函数
  • 函数之间要传递大量参数

范例:

package main

import (
    "errors"
    "fmt"
    "strconv"
)

// 用户登录,获取信息,更新信息,列出信息
var message = "This is old message"

func login(username string) (value int, isLogin bool, err error) {
    if username == "" {
        err = errors.New("user login faild")
        value = -1
        isLogin = false
        return
    } else {
        fmt.Println(username, "login successful")
        return 10, true, nil
    }
}

func getInfo(isLogin bool) (value *string, err error) {
    if isLogin {
        fmt.Println(message)
        return &message, nil
    } else {
        return nil, errors.New("user not login")
    }
}

func updateInfo(userid int, isLogin bool, message *string, newInfo string) (err error) {
    if userid != -1 && isLogin {
        *message = strconv.Itoa(userid) + " modified to " + newInfo
        fmt.Println("message update to ", *message)
        return nil
    } else if userid == -1 || !isLogin {
        return errors.New("user not login")
    } else {
        return errors.New("Message is nil")
    }
}

func main() {
    uid, loginState, login_err := login("janzen")
    if login_err != nil {
        panic(login_err)
    }
    msg, get_err := getInfo(loginState)
    if get_err != nil {
        panic(get_err)
    }
    up_err := updateInfo(uid, loginState, msg, "New Message")
    if up_err != nil {
        panic(up_err)
    }

    fmt.Println(message)
}

输出结果:

PS F:\go\go_project\test> go run .\Function-oriented-programming\Function-oriented.go
janzen login successful
This is old message
message update to  10 modified to New Message
10 modified to New Message

 

面向对象编程

  • 把大量参数封装到结构体中
  • 给结构体赋予方法,在成员方法内对结构体成员变量进行修改
  • go语言面向对象的好处:打包参数、继承、面向接口编程

 范例:

package main

import (
    "errors"
    "fmt"
    "strconv"
)

var Message = "This is old message"

type Client struct {
    UserName   string
    Uid        int
    LoginState bool
}

func Login(username string) (c *Client, err error) {
    if username == "" {
        err = errors.New("user login faild")
        c = nil
        return
    } else {
        fmt.Println(username, "login successful")
        c = &Client{username, 10, true}
        err = nil
        return
    }
}

func (c *Client) getInfo() (value *string, err error) {
    if c.LoginState {
        fmt.Println(Message)
        return &Message, nil
    } else {
        return nil, errors.New("user not login")
    }
}

func (c *Client) updateInfo(Message *string, newInfo string) (err error) {
    if c.Uid != -1 && c.LoginState && Message != nil {
        *Message = strconv.Itoa(c.Uid) + " modified to " + newInfo
        fmt.Println("message update to ", *Message)
        return nil
    } else if c.Uid == -1 || !c.LoginState {
        return errors.New("user not login")
    } else {
        return errors.New("Message is nil")
    }
}

func main() {
    c, login_err := Login("janzen")
    if login_err != nil {
        panic(login_err)
    }
    msg, get_err := c.getInfo()
    if get_err != nil {
        panic(get_err)
    }
    up_err := c.updateInfo(msg, "New Message")
    if up_err != nil {
        panic(up_err)
    }

    fmt.Println(Message)

}

输出结果: 

PS F:\go\go_project\test> go run .\Object-oriented-programming\Object-oriented-programming.go
janzen login successful
This is old message
message update to  10 modified to New Message
10 modified to New Message

 

二、构造函数

type User struct {
    Name string
    Age    uint8
    Sex byte
}

func main () {
    u1 := User{} // 构造一个空User, 各字段取相应的数据类型的默认值

    u2 = new(User) //构造一个空User,并返回该User结构体的指针

}

 

自定义构造函数

type User struct {
    Name string
    Age    int8
    Sex byte
}

func NewUserDefault() *User {
    return &User{
        Name: "",
        Age: -1,
        Sex: 3,
    }
}

func NewUser(name string, age int8,sex byte) *User {
    return &User{
        Name: name,
        Age: age,
        Sex: sex,
    }
}

 

单例模式

package main

import "sync"

var (
    sUser *User
    uOnce sync.Once  // 不同原子性操作,Once变量不可以共用,需要为每一个不同的原子性操作创建独立Once
)
func NewUserDefault() *User {
    return &User{
        Name: "",
        Age:  -1,
        Sex:  3,
    }
}

func NewUser(name string, age int8, sex byte) *User {
    return &User{
        Name: name,
        Age:  age,
        Sex:  sex,
    }
}

func getUser() *User {
    uOnce.Do(func() { //sync.Onec.DO 可以确保在并发情况下,下方代码块在整个go进程中只会被执行一次,原子性执行
        if sUser == nil {
            sUser = NewUserDefault()
        }
    })
    return sUser
}

 

 

三、继承与重写

继承

go语言设计思想中没有真正的继承关系

通过嵌入匿名结构体,变相实现实现“继承”的功能

范例:

type User struct {
    Name string
    Age  int8
    Sex  byte
}

type Student struct {
    User
    Grade byte
    Class byte
}

func main() {
    u := User{"janzen", 21, 1}
    s := Student{u, 3, 1}
    fmt.Printf("sNmae = %s, sAge = %d, sClass = %d", s.Name, s.Age, s.Class)

}

 输出结果:

PS F:\go\go_project\test> go run .\Constructor\Constructor.go
sNmae = janzen, sAge = 21, sClass = 1

  

重写

func (user User) level() int {
    return 10
}

// 重写父类 User level方法
func (student Student) level() int {
    return student.User.level() + 100  // 调用父类方法
}

 

组合

type User struct {
    Name string
    Age  int8
    Sex  byte
}

type Student struct {
    User
    Grade byte
    Class byte
}

// 通过组合使得 Persion 可以使用 User 和 Student 的全部方法和成员
type Persion struct {
    User
    Student
}

 

 

四、泛型

未使用泛型

未使用泛型不同数据类型之间不能直接进行逻辑运算,哪怕同为整型,int8 与 int16 也不能直接进行逻辑运算

func main() {

    aInt := int(8)
    bInt8 := int8(17)

    sumInt := aInt + bInt8
}
PS F:\go\go_project\test> go run .\FurnerStar\FurnerStar.go
# command-line-arguments
FurnerStar\FurnerStar.go:22:12: invalid operation: aInt + bInt8 (mismatched types int and int8)  c

 常用方式:

func AddString(a, b string) string {
    return a + b
}

func AddInt(a, b int) int {
    return a + b
}

func AddInt8(a, b int8) int8 {
    return a + b
}

func main() {

    var aInt,bInt int = 8,10
    var aInt8,bInt8 int8 = 7,19
    sumInt := AddInt(aInt, bInt)
    sumInt8 := AddInt8(aInt8, bInt8)
    sumStr := AddString("test ", "test2")

    fmt.Println(sumInt, sumInt8, sumStr)
}

 

 

使用泛型

type Addable interface {
    int|int8|int16|int32|int64|
    uint|uint8|uint16|uint32|uint64|
    float32|float64|
    string
}

func add[T Addable](a,b T)T{
    return a+b
}

func main() {

    var aInt,bInt int = 8,10
    var aInt8,bInt8 int8 = 7,19

    sum1 := add(aInt,bInt)
    sum2 := add(aInt8,bInt8)
    sum3 := add("test ", "test2")

    fmt.Println(sum1,sum2,sum3)
}

 

posted @ 2023-08-18 01:25  Janzen_Q  阅读(24)  评论(0编辑  收藏  举报