多态是面向对象编程的核心特性之一。本章将深入讲解 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)
}
}
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))
}
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"))
}
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 语言的接口多态:
| 知识点 | 说明 |
|---|---|
| 多态定义 | 同一接口,不同实现 |
| 接口切片 | 存储不同实现的对象 |
| 策略模式 | 运行时选择算法 |
| 工厂模式 | 创建对象的工厂 |
| 装饰器模式 | 动态添加功能 |