接口多态

多态是面向对象编程的核心特性之一。本章将深入讲解 Go 语言如何通过接口实现多态。

什么是多态?

多态是指同一接口,不同的实现。简单来说,就是"一种接口,多种形态"。

多态示意:

           ┌──────────┐
           │  接口 A   │
           └────┬─────┘
                │
      ┌─────────┼─────────┐
      ↓         ↓         ↓
  ┌───────┐ ┌───────┐ ┌───────┐
  │实现 A │ │实现 B │ │实现 C │
  └───────┘ └───────┘ └───────┘

多态基础

接口定义

type Shape interface {
    Area() float64
}

多种实现

package main

import (
    "fmt"
    "math"
)

type Shape interface {
    Area() float64
}

type Rectangle struct {
    Width, Height float64
}

func (r Rectangle) Area() float64 {
    return r.Width * r.Height
}

type Circle struct {
    Radius float64
}

func (c Circle) Area() float64 {
    return math.Pi * c.Radius * c.Radius
}

type Triangle struct {
    Base, Height float64
}

func (t Triangle) Area() float64 {
    return 0.5 * t.Base * t.Height
}

func PrintArea(s Shape) {
    fmt.Printf("面积: %.2f\n", s.Area())
}

func main() {
    shapes := []Shape{
        Rectangle{Width: 10, Height: 5},
        Circle{Radius: 5},
        Triangle{Base: 8, Height: 6},
    }

    for i, shape := range shapes {
        fmt.Printf("图形 %d: ", i+1)
        PrintArea(shape)
    }
}

多态应用场景

1. 策略模式

package main

import "fmt"

type SortStrategy interface {
    Sort([]int) []int
}

type BubbleSort struct{}

func (bs BubbleSort) Sort(arr []int) []int {
    result := make([]int, len(arr))
    copy(result, arr)
    n := len(result)
    for i := 0; i < n-1; i++ {
        for j := 0; j < n-i-1; j++ {
            if result[j] > result[j+1] {
                result[j], result[j+1] = result[j+1], result[j]
            }
        }
    }
    return result
}

type QuickSort struct{}

func (qs QuickSort) Sort(arr []int) []int {
    if len(arr) <= 1 {
        return arr
    }
    pivot := arr[0]
    var left, right []int
    for _, v := range arr[1:] {
        if v <= pivot {
            left = append(left, v)
        } else {
            right = append(right, v)
        }
    }
    result := append(qs.Sort(left), pivot)
    result = append(result, qs.Sort(right)...)
    return result
}

type Sorter struct {
    strategy SortStrategy
}

func (s *Sorter) SetStrategy(strategy SortStrategy) {
    s.strategy = strategy
}

func (s *Sorter) Sort(arr []int) []int {
    return s.strategy.Sort(arr)
}

func main() {
    arr := []int{64, 34, 25, 12, 22, 11, 90}

    sorter := &Sorter{}

    sorter.SetStrategy(BubbleSort{})
    fmt.Printf("冒泡排序: %v\n", sorter.Sort(arr))

    sorter.SetStrategy(QuickSort{})
    fmt.Printf("快速排序: %v\n", sorter.Sort(arr))
}

2. 工厂模式

package main

import "fmt"

type Database interface {
    Connect() string
    Query(sql string) string
}

type MySQL struct {
    Host string
}

func (m MySQL) Connect() string {
    return fmt.Sprintf("连接 MySQL: %s", m.Host)
}

func (m MySQL) Query(sql string) string {
    return fmt.Sprintf("MySQL 执行: %s", sql)
}

type PostgreSQL struct {
    Host string
}

func (p PostgreSQL) Connect() string {
    return fmt.Sprintf("连接 PostgreSQL: %s", p.Host)
}

func (p PostgreSQL) Query(sql string) string {
    return fmt.Sprintf("PostgreSQL 执行: %s", sql)
}

type DatabaseFactory struct{}

func (df DatabaseFactory) Create(dbType, host string) Database {
    switch dbType {
    case "mysql":
        return MySQL{Host: host}
    case "postgresql":
        return PostgreSQL{Host: host}
    default:
        return nil
    }
}

func main() {
    factory := DatabaseFactory{}

    mysql := factory.Create("mysql", "localhost:3306")
    fmt.Println(mysql.Connect())
    fmt.Println(mysql.Query("SELECT * FROM users"))

    postgres := factory.Create("postgresql", "localhost:5432")
    fmt.Println(postgres.Connect())
    fmt.Println(postgres.Query("SELECT * FROM users"))
}

3. 装饰器模式

package main

import "fmt"

type DataSource interface {
    Read() string
    Write(data string)
}

type FileDataSource struct {
    data string
}

func (fds *FileDataSource) Read() string {
    return fds.data
}

func (fds *FileDataSource) Write(data string) {
    fds.data = data
}

type EncryptionDecorator struct {
    source DataSource
}

func (ed *EncryptionDecorator) Read() string {
    data := ed.source.Read()
    return "解密(" + data + ")"
}

func (ed *EncryptionDecorator) Write(data string) {
    ed.source.Write("加密(" + data + ")")
}

type CompressionDecorator struct {
    source DataSource
}

func (cd *CompressionDecorator) Read() string {
    data := cd.source.Read()
    return "解压(" + data + ")"
}

func (cd *CompressionDecorator) Write(data string) {
    cd.source.Write("压缩(" + data + ")")
}

func main() {
    source := &FileDataSource{}

    source.Write("原始数据")
    fmt.Println("原始读取:", source.Read())

    encrypted := &EncryptionDecorator{source: source}
    encrypted.Write("敏感数据")
    fmt.Println("加密读取:", encrypted.Read())

    compressed := &CompressionDecorator{source: source}
    compressed.Write("大数据")
    fmt.Println("压缩读取:", compressed.Read())
}

接口切片

package main

import "fmt"

type Animal interface {
    Speak() string
}

type Dog struct{}

func (d Dog) Speak() string { return "汪汪" }

type Cat struct{}

func (c Cat) Speak() string { return "喵喵" }

type Cow struct{}

func (c Cow) Speak() string { return "哞哞" }

func main() {
    animals := []Animal{Dog{}, Cat{}, Cow{}}

    for _, animal := range animals {
        fmt.Println(animal.Speak())
    }
}

接口作为函数参数和返回值

package main

import "fmt"

type Processor interface {
    Process(string) string
}

type UpperCaseProcessor struct{}

func (u UpperCaseProcessor) Process(s string) string {
    result := ""
    for _, c := range s {
        if c >= 'a' && c <= 'z' {
            result += string(c - 32)
        } else {
            result += string(c)
        }
    }
    return result
}

type ReverseProcessor struct{}

func (r ReverseProcessor) Process(s string) string {
    runes := []rune(s)
    for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
        runes[i], runes[j] = runes[j], runes[i]
    }
    return string(runes)
}

func GetProcessor(processType string) Processor {
    switch processType {
    case "upper":
        return UpperCaseProcessor{}
    case "reverse":
        return ReverseProcessor{}
    default:
        return nil
    }
}

func ProcessData(data string, processor Processor) string {
    return processor.Process(data)
}

func main() {
    data := "Hello World"

    upper := GetProcessor("upper")
    fmt.Println(ProcessData(data, upper))

    reverse := GetProcessor("reverse")
    fmt.Println(ProcessData(data, reverse))
}

总结

本章学习了 Go 语言的接口多态:

知识点说明
多态定义同一接口,不同实现
接口切片存储不同实现的对象
策略模式运行时选择算法
工厂模式创建对象的工厂
装饰器模式动态添加功能