flyfei

Go的”面向对象”特性

1. 语法讲解

结构体定义

Go使用结构体替代类的概念:

type 结构体名 struct {
    字段1 类型
    字段2 类型
    // ...
}

方法定义

func (接收者 接收者类型) 方法名(参数列表) 返回值列表 {
    // 方法体
}

接收者可以是值类型或指针类型,指针类型可修改接收者的字段。

接口定义

type 接口名 interface {
    方法1(参数列表) 返回值列表
    方法2(参数列表) 返回值列表
    // ...
}  

当一个类型实现了接口中所有方法,就视为实现了该接口,无需显式声明

组合替代继承

Go通过结构体嵌入实现组合,匿名嵌入的字段和方法会自动提升到外部结构体。

Go通过接口嵌入组合实现混合的更灵活的接口定义

2. 应用场景

真实业务场景:电商平台用户系统 电商平台有不同类型的用户(普通用户、VIP用户),这些用户有共同属性(基础信息)和不同特性(权限、折扣等)。通过组合可以避免重复代码,同时保持类型之间的清晰关系。

3. 编程实例

package main

import (
    "fmt"
    "time"
)

// 基础用户信息
type BaseUser struct {
    ID        int
    Name      string
    Email     string
    CreatedAt time.Time
}

func (u *BaseUser) GetCreatedDate() string {
    return u.CreatedAt.Format("2006-01-02")
}

func (u *BaseUser) DisplayBasicInfo() {
    fmt.Printf("用户ID: %d, 姓名: %s, 邮箱: %s\n", u.ID, u.Name, u.Email)
}

// 地址信息
type Address struct {
    Province string
    City     string
    District string
    Detail   string
}

func (a Address) GetFullAddress() string {
    return fmt.Sprintf("%s%s%s%s", a.Province, a.City, a.District, a.Detail)
}

// 普通用户
type NormalUser struct {
    BaseUser           // 嵌入基础用户
    Addresses []Address // 多个地址
    Level     int       // 用户等级
}

func (nu *NormalUser) AddAddress(addr Address) {
    nu.Addresses = append(nu.Addresses, addr)
}

// VIP用户
type VIPUser struct {
    BaseUser           // 嵌入基础用户
    Addresses  []Address // 多个地址
    VIPLevel   int       // VIP等级
    Discount   float64   // 专属折扣
    ExpireTime time.Time // VIP到期时间
}

func (vu *VIPUser) IsVIPValid() bool {
    return time.Now().Before(vu.ExpireTime)
}

func (vu *VIPUser) GetDiscount() float64 {
    if vu.IsVIPValid() {
        return vu.Discount
    }
    return 1.0 // 无折扣
}

// 用户服务
type UserService struct{}

func (us *UserService) CreateUser(name, email string, userType string) interface{} {
    base := BaseUser{
        ID:        generateID(),
        Name:      name,
        Email:     email,
        CreatedAt: time.Now(),
    }
    
    switch userType {
    case "normal":
        return &NormalUser{
            BaseUser: base,
            Level:    1,
        }
    case "vip":
        return &VIPUser{
            BaseUser:   base,
            VIPLevel:   1,
            Discount:   0.9, // 9折
            ExpireTime: time.Now().AddDate(1, 0, 0), // 1年后到期
        }
    default:
        return nil
    }
}

func generateID() int {
    return int(time.Now().Unix())
}

func main() {
    service := &UserService{}
    
    // 创建不同类型的用户
    normalUser := service.CreateUser("张三", "zhangsan@example.com", "normal").(*NormalUser)
    vipUser := service.CreateUser("李四", "lisi@example.com", "vip").(*VIPUser)
    
    // 为用户添加地址
    addr := Address{
        Province: "广东省",
        City:     "深圳市",
        District: "南山区",
        Detail:   "科技园123号",
    }
    
    normalUser.AddAddress(addr)
    
    // 演示多态性 - 所有用户都有基础信息
    users := []interface{}{normalUser, vipUser}
    
    for _, user := range users {
        fmt.Println("\n=== 用户信息 ===")
        switch u := user.(type) {
        case *NormalUser:
            u.DisplayBasicInfo()
            fmt.Printf("用户等级: %d\n", u.Level)
            fmt.Printf("注册时间: %s\n", u.GetCreatedDate())
        case *VIPUser:
            u.DisplayBasicInfo()
            fmt.Printf("VIP等级: %d, 折扣: %.1f, 是否有效: %t\n", 
                u.VIPLevel, u.Discount, u.IsVIPValid())
    }
}

4. 其他用法

接口与组合结合使用

package main

import "fmt"

// 通知接口
type Notifier interface {
    Notify(message string) error
}

// 邮件通知
type EmailNotifier struct {
    SMTPHost string
    Port     int
}

func (en EmailNotifier) Notify(message string) error {
    fmt.Printf("发送邮件通知: %s\n", message)
    return nil
}

// 短信通知
type SMSNotifier struct {
    APIKey string
}

func (sn SMSNotifier) Notify(message string) error {
    fmt.Printf("发送短信通知: %s\n", message)
    return nil
}

// 应用服务
type OrderService struct {
    notifier Notifier // 组合接口
}

func (os *OrderService) SetNotifier(notifier Notifier) {
    os.notifier = notifier
}

func (os *OrderService) CreateOrder(product string, quantity int) {
    // 创建订单逻辑
    fmt.Printf("创建订单: %s x %d\n", product, quantity)
    
    // 发送通知
    message := fmt.Sprintf("订单创建成功: %s x %d", product, quantity)
    os.notifier.Notify(message)
}

// 广播通知 - 组合多个通知器
type BroadcastNotifier struct {
    notifiers []Notifier
}

func (bn BroadcastNotifier) Notify(message string) error {
    for _, notifier := range bn.notifiers {
        notifier.Notify(message)
    }
    return nil
}

func main() {
    orderService := &OrderService{}
    
    // 使用邮件通知
    emailNotifier := EmailNotifier{SMTPHost: "smtp.example.com", Port: 587}
    orderService.SetNotifier(emailNotifier)
    orderService.CreateOrder("iPhone 14", 2)
    
    // 切换为短信通知
    smsNotifier := SMSNotifier{APIKey: "your_api_key"}
    orderService.SetNotifier(smsNotifier)
    orderService.CreateOrder("MacBook Pro", 1)
    
    // 多种通知方式组合
    broadcastNotifier := BroadcastNotifier{
        notifiers: []Notifier{emailNotifier, smsNotifier},
    }
    orderService.SetNotifier(broadcastNotifier)
    orderService.CreateOrder("iPad Air", 3)
}


5. 课时总结