1340 lines
29 KiB
Go
1340 lines
29 KiB
Go
/*
|
||
01-basic-interfaces.go - Go 语言基础接口详解
|
||
|
||
学习目标:
|
||
1. 理解接口的概念和作用
|
||
2. 掌握接口的定义和实现
|
||
3. 学会接口的多态特性
|
||
4. 了解接口的组合
|
||
5. 掌握接口的实际应用场景
|
||
|
||
知识点:
|
||
- 接口的定义和特性
|
||
- 接口的实现(隐式实现)
|
||
- 接口的多态性
|
||
- 接口的组合
|
||
- 接口与结构体的关系
|
||
- 接口的最佳实践
|
||
*/
|
||
|
||
package main
|
||
|
||
import (
|
||
"fmt"
|
||
)
|
||
|
||
func main() {
|
||
fmt.Println("=== Go 语言基础接口详解 ===\n")
|
||
|
||
// 演示接口的基本概念
|
||
demonstrateBasicInterfaces()
|
||
|
||
// 演示接口的实现
|
||
demonstrateInterfaceImplementation()
|
||
|
||
// 演示接口的多态性
|
||
demonstratePolymorphism()
|
||
|
||
// 演示接口的组合
|
||
demonstrateInterfaceComposition()
|
||
|
||
// 演示接口与结构体
|
||
demonstrateInterfacesWithStructs()
|
||
|
||
// 演示接口的高级用法
|
||
demonstrateAdvancedInterfaceUsage()
|
||
|
||
// 演示接口的实际应用
|
||
demonstratePracticalApplications()
|
||
}
|
||
|
||
// demonstrateBasicInterfaces 演示接口的基本概念
|
||
func demonstrateBasicInterfaces() {
|
||
fmt.Println("1. 接口的基本概念:")
|
||
|
||
// 接口的基本特性
|
||
fmt.Printf(" 接口的基本特性:\n")
|
||
fmt.Printf(" - 定义方法签名的集合\n")
|
||
fmt.Printf(" - 隐式实现,无需显式声明\n")
|
||
fmt.Printf(" - 支持多态和抽象\n")
|
||
fmt.Printf(" - 接口类型的零值是 nil\n")
|
||
fmt.Printf(" - 接口可以嵌入其他接口\n")
|
||
|
||
// 基本接口示例
|
||
fmt.Printf(" 基本接口示例:\n")
|
||
|
||
// 创建不同的形状
|
||
var shape Shape
|
||
|
||
// 圆形
|
||
circle := Circle{Radius: 5}
|
||
shape = circle
|
||
fmt.Printf(" 圆形面积: %.2f\n", shape.Area())
|
||
fmt.Printf(" 圆形周长: %.2f\n", shape.Perimeter())
|
||
|
||
// 矩形
|
||
rectangle := Rectangle{Width: 4, Height: 6}
|
||
shape = rectangle
|
||
fmt.Printf(" 矩形面积: %.2f\n", shape.Area())
|
||
fmt.Printf(" 矩形周长: %.2f\n", shape.Perimeter())
|
||
|
||
// 三角形
|
||
triangle := Triangle{Base: 8, Height: 6}
|
||
shape = triangle
|
||
fmt.Printf(" 三角形面积: %.2f\n", shape.Area())
|
||
fmt.Printf(" 三角形周长: %.2f\n", shape.Perimeter())
|
||
|
||
// 接口的零值
|
||
fmt.Printf(" 接口的零值:\n")
|
||
var nilShape Shape
|
||
fmt.Printf(" nil 接口: %v\n", nilShape)
|
||
fmt.Printf(" nil 接口 == nil: %t\n", nilShape == nil)
|
||
|
||
// 检查接口是否为 nil
|
||
if nilShape == nil {
|
||
fmt.Printf(" 接口为 nil,不能调用方法\n")
|
||
}
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateInterfaceImplementation 演示接口的实现
|
||
func demonstrateInterfaceImplementation() {
|
||
fmt.Println("2. 接口的实现:")
|
||
|
||
fmt.Printf(" Go 语言的接口实现是隐式的\n")
|
||
fmt.Printf(" 只要类型实现了接口的所有方法,就自动实现了该接口\n")
|
||
|
||
// 演示隐式实现
|
||
fmt.Printf(" 隐式实现示例:\n")
|
||
|
||
// Writer 接口的不同实现
|
||
var writer Writer
|
||
|
||
// 文件写入器
|
||
fileWriter := &FileWriter{filename: "output.txt"}
|
||
writer = fileWriter
|
||
writer.Write([]byte("Hello, File!"))
|
||
|
||
// 控制台写入器
|
||
consoleWriter := &ConsoleWriter{}
|
||
writer = consoleWriter
|
||
writer.Write([]byte("Hello, Console!"))
|
||
|
||
// 内存写入器
|
||
memoryWriter := &MemoryWriter{}
|
||
writer = memoryWriter
|
||
writer.Write([]byte("Hello, Memory!"))
|
||
fmt.Printf(" 内存写入器内容: %s\n", string(memoryWriter.buffer))
|
||
|
||
// 接口方法的调用
|
||
fmt.Printf(" 接口方法调用:\n")
|
||
|
||
// 创建不同的动物
|
||
animals := []Animal{
|
||
Dog{Name: "旺财"},
|
||
Cat{Name: "咪咪"},
|
||
Bird{Name: "小鸟"},
|
||
}
|
||
|
||
for _, animal := range animals {
|
||
fmt.Printf(" %s: %s\n", animal.Name(), animal.Sound())
|
||
animal.Move()
|
||
}
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstratePolymorphism 演示接口的多态性
|
||
func demonstratePolymorphism() {
|
||
fmt.Println("3. 接口的多态性:")
|
||
|
||
fmt.Printf(" 多态允许不同类型以统一的方式处理\n")
|
||
|
||
// 形状多态示例
|
||
fmt.Printf(" 形状多态示例:\n")
|
||
|
||
shapes := []Shape{
|
||
Circle{Radius: 3},
|
||
Rectangle{Width: 4, Height: 5},
|
||
Triangle{Base: 6, Height: 4},
|
||
Circle{Radius: 2},
|
||
}
|
||
|
||
totalArea := 0.0
|
||
for i, shape := range shapes {
|
||
area := shape.Area()
|
||
fmt.Printf(" 形状 %d 面积: %.2f\n", i+1, area)
|
||
totalArea += area
|
||
}
|
||
fmt.Printf(" 总面积: %.2f\n", totalArea)
|
||
|
||
// 支付方式多态示例
|
||
fmt.Printf(" 支付方式多态示例:\n")
|
||
|
||
paymentMethods := []PaymentMethod{
|
||
CreditCard{CardNumber: "1234-5678-9012-3456", Balance: 1000},
|
||
PayPal{Email: "user@example.com", Balance: 500},
|
||
Cash{Amount: 200},
|
||
}
|
||
|
||
totalAmount := 300.0
|
||
for _, method := range paymentMethods {
|
||
fmt.Printf(" 使用 %s 支付:\n", method.GetName())
|
||
if method.Pay(totalAmount) {
|
||
fmt.Printf(" 支付成功!\n")
|
||
break
|
||
} else {
|
||
fmt.Printf(" 支付失败,余额不足\n")
|
||
}
|
||
}
|
||
|
||
// 排序接口多态
|
||
fmt.Printf(" 排序接口多态:\n")
|
||
|
||
// 整数排序
|
||
numbers := IntSlice{64, 34, 25, 12, 22, 11, 90}
|
||
fmt.Printf(" 排序前: %v\n", numbers)
|
||
Sort(numbers)
|
||
fmt.Printf(" 排序后: %v\n", numbers)
|
||
|
||
// 字符串排序
|
||
words := StringSlice{"banana", "apple", "cherry", "date"}
|
||
fmt.Printf(" 排序前: %v\n", words)
|
||
Sort(words)
|
||
fmt.Printf(" 排序后: %v\n", words)
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateInterfaceComposition 演示接口的组合
|
||
func demonstrateInterfaceComposition() {
|
||
fmt.Println("4. 接口的组合:")
|
||
|
||
fmt.Printf(" 接口可以嵌入其他接口,实现接口组合\n")
|
||
|
||
// 读写器组合示例
|
||
fmt.Printf(" 读写器组合示例:\n")
|
||
|
||
// 文件读写器实现了 ReadWriter 接口
|
||
var rw ReadWriter = &FileReadWriter{
|
||
filename: "test.txt",
|
||
content: "Initial content",
|
||
}
|
||
|
||
// 写入数据
|
||
data := []byte("Hello, ReadWriter!")
|
||
n := rw.Write(data)
|
||
fmt.Printf(" 写入 %d 字节\n", n)
|
||
|
||
// 读取数据
|
||
buffer := make([]byte, 50)
|
||
n = rw.Read(buffer)
|
||
fmt.Printf(" 读取 %d 字节: %s\n", n, string(buffer[:n]))
|
||
|
||
// 关闭资源
|
||
if closer, ok := rw.(Closer); ok {
|
||
closer.Close()
|
||
fmt.Printf(" 资源已关闭\n")
|
||
}
|
||
|
||
// 多接口组合
|
||
fmt.Printf(" 多接口组合示例:\n")
|
||
|
||
// 多媒体播放器
|
||
var player MediaPlayer = &VideoPlayer{
|
||
filename: "movie.mp4",
|
||
volume: 80,
|
||
position: 0,
|
||
}
|
||
|
||
// 播放控制
|
||
player.Play()
|
||
player.SetVolume(90)
|
||
player.Seek(120) // 跳转到2分钟
|
||
|
||
// 如果支持视频控制
|
||
if videoCtrl, ok := player.(VideoController); ok {
|
||
videoCtrl.SetBrightness(75)
|
||
videoCtrl.SetContrast(85)
|
||
fmt.Printf(" 视频控制设置完成\n")
|
||
}
|
||
|
||
player.Pause()
|
||
player.Stop()
|
||
|
||
fmt.Println()
|
||
}// demons
|
||
trateInterfacesWithStructs 演示接口与结构体
|
||
func demonstrateInterfacesWithStructs() {
|
||
fmt.Println("5. 接口与结构体:")
|
||
|
||
// 结构体实现接口
|
||
fmt.Printf(" 结构体实现接口:\n")
|
||
|
||
// 创建员工
|
||
employees := []Employee{
|
||
Developer{
|
||
Name: "Alice",
|
||
Language: "Go",
|
||
Experience: 5,
|
||
},
|
||
Manager{
|
||
Name: "Bob",
|
||
Department: "Engineering",
|
||
TeamSize: 10,
|
||
},
|
||
Designer{
|
||
Name: "Charlie",
|
||
Tool: "Figma",
|
||
Portfolio: []string{"App UI", "Web Design"},
|
||
},
|
||
}
|
||
|
||
// 计算总薪资
|
||
totalSalary := 0.0
|
||
for _, emp := range employees {
|
||
salary := emp.GetSalary()
|
||
fmt.Printf(" %s (%s): $%.2f\n", emp.GetName(), emp.GetRole(), salary)
|
||
totalSalary += salary
|
||
}
|
||
fmt.Printf(" 总薪资: $%.2f\n", totalSalary)
|
||
|
||
// 让员工工作
|
||
fmt.Printf(" 员工工作:\n")
|
||
for _, emp := range employees {
|
||
emp.Work()
|
||
}
|
||
|
||
// 接口作为结构体字段
|
||
fmt.Printf(" 接口作为结构体字段:\n")
|
||
|
||
// 创建通知系统
|
||
notifier := NotificationSystem{
|
||
providers: []NotificationProvider{
|
||
EmailProvider{SMTPServer: "smtp.example.com"},
|
||
SMSProvider{APIKey: "sms-api-key"},
|
||
PushProvider{AppID: "push-app-id"},
|
||
},
|
||
}
|
||
|
||
// 发送通知
|
||
message := "系统维护通知:服务将在今晚10点进行维护"
|
||
notifier.SendNotification(message)
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateAdvancedInterfaceUsage 演示接口的高级用法
|
||
func demonstrateAdvancedInterfaceUsage() {
|
||
fmt.Println("6. 接口的高级用法:")
|
||
|
||
// 接口作为参数
|
||
fmt.Printf(" 接口作为参数:\n")
|
||
|
||
shapes := []Shape{
|
||
Circle{Radius: 2},
|
||
Rectangle{Width: 3, Height: 4},
|
||
Triangle{Base: 5, Height: 6},
|
||
}
|
||
|
||
// 计算总面积
|
||
total := calculateTotalArea(shapes)
|
||
fmt.Printf(" 所有形状总面积: %.2f\n", total)
|
||
|
||
// 找出最大面积的形状
|
||
largest := findLargestShape(shapes)
|
||
fmt.Printf(" 最大面积: %.2f\n", largest.Area())
|
||
|
||
// 接口作为返回值
|
||
fmt.Printf(" 接口作为返回值:\n")
|
||
|
||
// 创建不同类型的数据库连接
|
||
mysqlDB := createDatabase("mysql")
|
||
postgresDB := createDatabase("postgres")
|
||
redisDB := createDatabase("redis")
|
||
|
||
// 使用数据库
|
||
mysqlDB.Connect()
|
||
mysqlDB.Query("SELECT * FROM users")
|
||
mysqlDB.Close()
|
||
|
||
postgresDB.Connect()
|
||
postgresDB.Query("SELECT * FROM products")
|
||
postgresDB.Close()
|
||
|
||
redisDB.Connect()
|
||
redisDB.Query("GET user:123")
|
||
redisDB.Close()
|
||
|
||
// 接口切片
|
||
fmt.Printf(" 接口切片:\n")
|
||
|
||
var items []fmt.Stringer
|
||
items = append(items, Circle{Radius: 3})
|
||
items = append(items, Rectangle{Width: 4, Height: 5})
|
||
items = append(items, Person{Name: "Alice", Age: 30})
|
||
|
||
fmt.Printf(" 接口切片内容:\n")
|
||
for i, item := range items {
|
||
fmt.Printf(" %d: %s\n", i+1, item.String())
|
||
}
|
||
|
||
// 接口嵌套
|
||
fmt.Printf(" 接口嵌套:\n")
|
||
|
||
// HTTP 服务器
|
||
server := &HTTPServer{
|
||
port: 8080,
|
||
routes: map[string]string{
|
||
"/": "Welcome",
|
||
"/about": "About Us",
|
||
},
|
||
}
|
||
|
||
// 启动服务器
|
||
server.Start()
|
||
server.HandleRequest("/")
|
||
server.HandleRequest("/about")
|
||
server.Stop()
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstratePracticalApplications 演示接口的实际应用
|
||
func demonstratePracticalApplications() {
|
||
fmt.Println("7. 接口的实际应用:")
|
||
|
||
// 应用1: 插件系统
|
||
fmt.Printf(" 应用1 - 插件系统:\n")
|
||
|
||
pluginManager := PluginManager{}
|
||
|
||
// 注册插件
|
||
pluginManager.RegisterPlugin(&LoggingPlugin{})
|
||
pluginManager.RegisterPlugin(&CachePlugin{})
|
||
pluginManager.RegisterPlugin(&SecurityPlugin{})
|
||
|
||
// 执行插件
|
||
pluginManager.ExecutePlugins("用户登录")
|
||
|
||
// 应用2: 策略模式
|
||
fmt.Printf(" 应用2 - 策略模式:\n")
|
||
|
||
// 不同的排序策略
|
||
data := []int{64, 34, 25, 12, 22, 11, 90}
|
||
|
||
sorter := DataSorter{data: make([]int, len(data))}
|
||
|
||
// 使用冒泡排序
|
||
copy(sorter.data, data)
|
||
sorter.SetStrategy(&BubbleSort{})
|
||
fmt.Printf(" 原始数据: %v\n", data)
|
||
sorter.Sort()
|
||
fmt.Printf(" 冒泡排序: %v\n", sorter.data)
|
||
|
||
// 使用快速排序
|
||
copy(sorter.data, data)
|
||
sorter.SetStrategy(&QuickSort{})
|
||
sorter.Sort()
|
||
fmt.Printf(" 快速排序: %v\n", sorter.data)
|
||
|
||
// 应用3: 观察者模式
|
||
fmt.Printf(" 应用3 - 观察者模式:\n")
|
||
|
||
// 创建主题
|
||
subject := &NewsAgency{}
|
||
|
||
// 创建观察者
|
||
tv := &TVChannel{name: "新闻频道"}
|
||
radio := &RadioStation{name: "广播电台"}
|
||
website := &NewsWebsite{name: "新闻网站"}
|
||
|
||
// 订阅
|
||
subject.Subscribe(tv)
|
||
subject.Subscribe(radio)
|
||
subject.Subscribe(website)
|
||
|
||
// 发布新闻
|
||
subject.PublishNews("重大新闻:Go 语言发布新版本!")
|
||
|
||
// 应用4: 工厂模式
|
||
fmt.Printf(" 应用4 - 工厂模式:\n")
|
||
|
||
// 创建不同类型的日志记录器
|
||
loggers := []Logger{
|
||
CreateLogger("file"),
|
||
CreateLogger("console"),
|
||
CreateLogger("database"),
|
||
}
|
||
|
||
message := "这是一条测试日志"
|
||
for _, logger := range loggers {
|
||
logger.Log(message)
|
||
}
|
||
|
||
// 应用5: 适配器模式
|
||
fmt.Printf(" 应用5 - 适配器模式:\n")
|
||
|
||
// 旧系统
|
||
oldSystem := &OldPaymentSystem{}
|
||
|
||
// 使用适配器
|
||
adapter := &PaymentAdapter{oldSystem: oldSystem}
|
||
|
||
// 通过新接口使用旧系统
|
||
var newPayment NewPaymentInterface = adapter
|
||
newPayment.ProcessPayment(100.0, "USD")
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// ========== 接口定义 ==========
|
||
|
||
// 基本形状接口
|
||
type Shape interface {
|
||
Area() float64
|
||
Perimeter() float64
|
||
}
|
||
|
||
// 写入器接口
|
||
type Writer interface {
|
||
Write([]byte) int
|
||
}
|
||
|
||
// 动物接口
|
||
type Animal interface {
|
||
Name() string
|
||
Sound() string
|
||
Move()
|
||
}
|
||
|
||
// 支付方法接口
|
||
type PaymentMethod interface {
|
||
Pay(amount float64) bool
|
||
GetName() string
|
||
}
|
||
|
||
// 排序接口
|
||
type Sortable interface {
|
||
Len() int
|
||
Less(i, j int) bool
|
||
Swap(i, j int)
|
||
}
|
||
|
||
// 读取器接口
|
||
type Reader interface {
|
||
Read([]byte) int
|
||
}
|
||
|
||
// 读写器接口(组合接口)
|
||
type ReadWriter interface {
|
||
Reader
|
||
Writer
|
||
}
|
||
|
||
// 关闭器接口
|
||
type Closer interface {
|
||
Close()
|
||
}
|
||
|
||
// 媒体播放器接口
|
||
type MediaPlayer interface {
|
||
Play()
|
||
Pause()
|
||
Stop()
|
||
SetVolume(volume int)
|
||
Seek(position int)
|
||
}
|
||
|
||
// 视频控制器接口
|
||
type VideoController interface {
|
||
SetBrightness(brightness int)
|
||
SetContrast(contrast int)
|
||
}
|
||
|
||
// 员工接口
|
||
type Employee interface {
|
||
GetName() string
|
||
GetRole() string
|
||
GetSalary() float64
|
||
Work()
|
||
}
|
||
|
||
// 通知提供者接口
|
||
type NotificationProvider interface {
|
||
SendNotification(message string) error
|
||
}
|
||
|
||
// 数据库接口
|
||
type Database interface {
|
||
Connect() error
|
||
Query(sql string) ([]map[string]interface{}, error)
|
||
Close() error
|
||
}
|
||
|
||
// 服务器接口
|
||
type Server interface {
|
||
Start() error
|
||
Stop() error
|
||
HandleRequest(path string) string
|
||
}
|
||
|
||
// 插件接口
|
||
type Plugin interface {
|
||
Name() string
|
||
Execute(data interface{}) error
|
||
}
|
||
|
||
// 排序策略接口
|
||
type SortStrategy interface {
|
||
Sort([]int)
|
||
}
|
||
|
||
// 观察者接口
|
||
type Observer interface {
|
||
Update(news string)
|
||
}
|
||
|
||
// 主题接口
|
||
type Subject interface {
|
||
Subscribe(observer Observer)
|
||
Unsubscribe(observer Observer)
|
||
Notify(news string)
|
||
}
|
||
|
||
// 日志记录器接口
|
||
type Logger interface {
|
||
Log(message string)
|
||
}
|
||
|
||
// 新支付接口
|
||
type NewPaymentInterface interface {
|
||
ProcessPayment(amount float64, currency string) bool
|
||
}
|
||
|
||
// ========== 结构体实现 ==========
|
||
|
||
// 圆形
|
||
type Circle struct {
|
||
Radius float64
|
||
}
|
||
|
||
func (c Circle) Area() float64 {
|
||
return math.Pi * c.Radius * c.Radius
|
||
}
|
||
|
||
func (c Circle) Perimeter() float64 {
|
||
return 2 * math.Pi * c.Radius
|
||
}
|
||
|
||
func (c Circle) String() string {
|
||
return fmt.Sprintf("Circle(radius=%.1f)", c.Radius)
|
||
}
|
||
|
||
// 矩形
|
||
type Rectangle struct {
|
||
Width, Height float64
|
||
}
|
||
|
||
func (r Rectangle) Area() float64 {
|
||
return r.Width * r.Height
|
||
}
|
||
|
||
func (r Rectangle) Perimeter() float64 {
|
||
return 2 * (r.Width + r.Height)
|
||
}
|
||
|
||
func (r Rectangle) String() string {
|
||
return fmt.Sprintf("Rectangle(%.1fx%.1f)", r.Width, r.Height)
|
||
}
|
||
|
||
// 三角形
|
||
type Triangle struct {
|
||
Base, Height float64
|
||
}
|
||
|
||
func (t Triangle) Area() float64 {
|
||
return 0.5 * t.Base * t.Height
|
||
}
|
||
|
||
func (t Triangle) Perimeter() float64 {
|
||
// 假设是等腰三角形
|
||
side := math.Sqrt((t.Base/2)*(t.Base/2) + t.Height*t.Height)
|
||
return t.Base + 2*side
|
||
}
|
||
|
||
func (t Triangle) String() string {
|
||
return fmt.Sprintf("Triangle(base=%.1f, height=%.1f)", t.Base, t.Height)
|
||
}
|
||
|
||
// 文件写入器
|
||
type FileWriter struct {
|
||
filename string
|
||
}
|
||
|
||
func (fw *FileWriter) Write(data []byte) int {
|
||
fmt.Printf(" 写入文件 %s: %s\n", fw.filename, string(data))
|
||
return len(data)
|
||
}
|
||
|
||
// 控制台写入器
|
||
type ConsoleWriter struct{}
|
||
|
||
func (cw *ConsoleWriter) Write(data []byte) int {
|
||
fmt.Printf(" 控制台输出: %s\n", string(data))
|
||
return len(data)
|
||
}
|
||
|
||
// 内存写入器
|
||
type MemoryWriter struct {
|
||
buffer []byte
|
||
}
|
||
|
||
func (mw *MemoryWriter) Write(data []byte) int {
|
||
mw.buffer = append(mw.buffer, data...)
|
||
fmt.Printf(" 写入内存: %s\n", string(data))
|
||
return len(data)
|
||
}
|
||
|
||
// 狗
|
||
type Dog struct {
|
||
Name string
|
||
}
|
||
|
||
func (d Dog) Name() string { return d.Name }
|
||
func (d Dog) Sound() string { return "汪汪" }
|
||
func (d Dog) Move() { fmt.Printf(" %s 在跑步\n", d.Name) }
|
||
|
||
// 猫
|
||
type Cat struct {
|
||
Name string
|
||
}
|
||
|
||
func (c Cat) Name() string { return c.Name }
|
||
func (c Cat) Sound() string { return "喵喵" }
|
||
func (c Cat) Move() { fmt.Printf(" %s 在悄悄走路\n", c.Name) }
|
||
|
||
// 鸟
|
||
type Bird struct {
|
||
Name string
|
||
}
|
||
|
||
func (b Bird) Name() string { return b.Name }
|
||
func (b Bird) Sound() string { return "啾啾" }
|
||
func (b Bird) Move() { fmt.Printf(" %s 在飞翔\n", b.Name) }
|
||
|
||
// 信用卡
|
||
type CreditCard struct {
|
||
CardNumber string
|
||
Balance float64
|
||
}
|
||
|
||
func (cc CreditCard) Pay(amount float64) bool {
|
||
if cc.Balance >= amount {
|
||
fmt.Printf(" 信用卡支付 $%.2f 成功\n", amount)
|
||
return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
func (cc CreditCard) GetName() string {
|
||
return "信用卡"
|
||
}
|
||
|
||
// PayPal
|
||
type PayPal struct {
|
||
Email string
|
||
Balance float64
|
||
}
|
||
|
||
func (pp PayPal) Pay(amount float64) bool {
|
||
if pp.Balance >= amount {
|
||
fmt.Printf(" PayPal 支付 $%.2f 成功\n", amount)
|
||
return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
func (pp PayPal) GetName() string {
|
||
return "PayPal"
|
||
}
|
||
|
||
// 现金
|
||
type Cash struct {
|
||
Amount float64
|
||
}
|
||
|
||
func (c Cash) Pay(amount float64) bool {
|
||
if c.Amount >= amount {
|
||
fmt.Printf(" 现金支付 $%.2f 成功\n", amount)
|
||
return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
func (c Cash) GetName() string {
|
||
return "现金"
|
||
}
|
||
|
||
// 整数切片排序
|
||
type IntSlice []int
|
||
|
||
func (is IntSlice) Len() int { return len(is) }
|
||
func (is IntSlice) Less(i, j int) bool { return is[i] < is[j] }
|
||
func (is IntSlice) Swap(i, j int) { is[i], is[j] = is[j], is[i] }
|
||
|
||
// 字符串切片排序
|
||
type StringSlice []string
|
||
|
||
func (ss StringSlice) Len() int { return len(ss) }
|
||
func (ss StringSlice) Less(i, j int) bool { return ss[i] < ss[j] }
|
||
func (ss StringSlice) Swap(i, j int) { ss[i], ss[j] = ss[j], ss[i] }
|
||
|
||
// 文件读写器
|
||
type FileReadWriter struct {
|
||
filename string
|
||
content string
|
||
}
|
||
|
||
func (frw *FileReadWriter) Read(data []byte) int {
|
||
n := copy(data, []byte(frw.content))
|
||
fmt.Printf(" 从文件 %s 读取 %d 字节\n", frw.filename, n)
|
||
return n
|
||
}
|
||
|
||
func (frw *FileReadWriter) Write(data []byte) int {
|
||
frw.content = string(data)
|
||
fmt.Printf(" 写入文件 %s: %s\n", frw.filename, string(data))
|
||
return len(data)
|
||
}
|
||
|
||
func (frw *FileReadWriter) Close() {
|
||
fmt.Printf(" 关闭文件 %s\n", frw.filename)
|
||
}
|
||
|
||
// 视频播放器
|
||
type VideoPlayer struct {
|
||
filename string
|
||
volume int
|
||
position int
|
||
}
|
||
|
||
func (vp *VideoPlayer) Play() {
|
||
fmt.Printf(" 播放视频: %s\n", vp.filename)
|
||
}
|
||
|
||
func (vp *VideoPlayer) Pause() {
|
||
fmt.Printf(" 暂停视频: %s\n", vp.filename)
|
||
}
|
||
|
||
func (vp *VideoPlayer) Stop() {
|
||
fmt.Printf(" 停止视频: %s\n", vp.filename)
|
||
}
|
||
|
||
func (vp *VideoPlayer) SetVolume(volume int) {
|
||
vp.volume = volume
|
||
fmt.Printf(" 设置音量: %d\n", volume)
|
||
}
|
||
|
||
func (vp *VideoPlayer) Seek(position int) {
|
||
vp.position = position
|
||
fmt.Printf(" 跳转到位置: %d 秒\n", position)
|
||
}
|
||
|
||
func (vp *VideoPlayer) SetBrightness(brightness int) {
|
||
fmt.Printf(" 设置亮度: %d\n", brightness)
|
||
}
|
||
|
||
func (vp *VideoPlayer) SetContrast(contrast int) {
|
||
fmt.Printf(" 设置对比度: %d\n", contrast)
|
||
}// 开发者
|
||
ty
|
||
pe Developer struct {
|
||
Name string
|
||
Language string
|
||
Experience int
|
||
}
|
||
|
||
func (d Developer) GetName() string { return d.Name }
|
||
func (d Developer) GetRole() string { return "开发者" }
|
||
func (d Developer) GetSalary() float64 { return float64(d.Experience) * 10000 }
|
||
func (d Developer) Work() { fmt.Printf(" %s 正在用 %s 编程\n", d.Name, d.Language) }
|
||
|
||
// 经理
|
||
type Manager struct {
|
||
Name string
|
||
Department string
|
||
TeamSize int
|
||
}
|
||
|
||
func (m Manager) GetName() string { return m.Name }
|
||
func (m Manager) GetRole() string { return "经理" }
|
||
func (m Manager) GetSalary() float64 { return float64(m.TeamSize) * 8000 }
|
||
func (m Manager) Work() { fmt.Printf(" %s 正在管理 %s 部门\n", m.Name, m.Department) }
|
||
|
||
// 设计师
|
||
type Designer struct {
|
||
Name string
|
||
Tool string
|
||
Portfolio []string
|
||
}
|
||
|
||
func (d Designer) GetName() string { return d.Name }
|
||
func (d Designer) GetRole() string { return "设计师" }
|
||
func (d Designer) GetSalary() float64 { return float64(len(d.Portfolio)) * 12000 }
|
||
func (d Designer) Work() { fmt.Printf(" %s 正在用 %s 设计\n", d.Name, d.Tool) }
|
||
|
||
// 通知系统
|
||
type NotificationSystem struct {
|
||
providers []NotificationProvider
|
||
}
|
||
|
||
func (ns *NotificationSystem) SendNotification(message string) {
|
||
for _, provider := range ns.providers {
|
||
provider.SendNotification(message)
|
||
}
|
||
}
|
||
|
||
// 邮件提供者
|
||
type EmailProvider struct {
|
||
SMTPServer string
|
||
}
|
||
|
||
func (ep EmailProvider) SendNotification(message string) error {
|
||
fmt.Printf(" 通过邮件发送: %s\n", message)
|
||
return nil
|
||
}
|
||
|
||
// 短信提供者
|
||
type SMSProvider struct {
|
||
APIKey string
|
||
}
|
||
|
||
func (sp SMSProvider) SendNotification(message string) error {
|
||
fmt.Printf(" 通过短信发送: %s\n", message)
|
||
return nil
|
||
}
|
||
|
||
// 推送提供者
|
||
type PushProvider struct {
|
||
AppID string
|
||
}
|
||
|
||
func (pp PushProvider) SendNotification(message string) error {
|
||
fmt.Printf(" 通过推送发送: %s\n", message)
|
||
return nil
|
||
}
|
||
|
||
// MySQL 数据库
|
||
type MySQL struct{}
|
||
|
||
func (m MySQL) Connect() error {
|
||
fmt.Printf(" 连接到 MySQL 数据库\n")
|
||
return nil
|
||
}
|
||
|
||
func (m MySQL) Query(sql string) ([]map[string]interface{}, error) {
|
||
fmt.Printf(" 执行 MySQL 查询: %s\n", sql)
|
||
return nil, nil
|
||
}
|
||
|
||
func (m MySQL) Close() error {
|
||
fmt.Printf(" 关闭 MySQL 连接\n")
|
||
return nil
|
||
}
|
||
|
||
// PostgreSQL 数据库
|
||
type PostgreSQL struct{}
|
||
|
||
func (p PostgreSQL) Connect() error {
|
||
fmt.Printf(" 连接到 PostgreSQL 数据库\n")
|
||
return nil
|
||
}
|
||
|
||
func (p PostgreSQL) Query(sql string) ([]map[string]interface{}, error) {
|
||
fmt.Printf(" 执行 PostgreSQL 查询: %s\n", sql)
|
||
return nil, nil
|
||
}
|
||
|
||
func (p PostgreSQL) Close() error {
|
||
fmt.Printf(" 关闭 PostgreSQL 连接\n")
|
||
return nil
|
||
}
|
||
|
||
// Redis 数据库
|
||
type Redis struct{}
|
||
|
||
func (r Redis) Connect() error {
|
||
fmt.Printf(" 连接到 Redis 数据库\n")
|
||
return nil
|
||
}
|
||
|
||
func (r Redis) Query(cmd string) ([]map[string]interface{}, error) {
|
||
fmt.Printf(" 执行 Redis 命令: %s\n", cmd)
|
||
return nil, nil
|
||
}
|
||
|
||
func (r Redis) Close() error {
|
||
fmt.Printf(" 关闭 Redis 连接\n")
|
||
return nil
|
||
}
|
||
|
||
// Person 结构体
|
||
type Person struct {
|
||
Name string
|
||
Age int
|
||
}
|
||
|
||
func (p Person) String() string {
|
||
return fmt.Sprintf("Person(name=%s, age=%d)", p.Name, p.Age)
|
||
}
|
||
|
||
// HTTP 服务器
|
||
type HTTPServer struct {
|
||
port int
|
||
routes map[string]string
|
||
}
|
||
|
||
func (hs *HTTPServer) Start() error {
|
||
fmt.Printf(" HTTP 服务器在端口 %d 启动\n", hs.port)
|
||
return nil
|
||
}
|
||
|
||
func (hs *HTTPServer) Stop() error {
|
||
fmt.Printf(" HTTP 服务器停止\n")
|
||
return nil
|
||
}
|
||
|
||
func (hs *HTTPServer) HandleRequest(path string) string {
|
||
if response, exists := hs.routes[path]; exists {
|
||
fmt.Printf(" 处理请求 %s: %s\n", path, response)
|
||
return response
|
||
}
|
||
fmt.Printf(" 404: 路径 %s 未找到\n", path)
|
||
return "404 Not Found"
|
||
}
|
||
|
||
// 插件管理器
|
||
type PluginManager struct {
|
||
plugins []Plugin
|
||
}
|
||
|
||
func (pm *PluginManager) RegisterPlugin(plugin Plugin) {
|
||
pm.plugins = append(pm.plugins, plugin)
|
||
fmt.Printf(" 注册插件: %s\n", plugin.Name())
|
||
}
|
||
|
||
func (pm *PluginManager) ExecutePlugins(data interface{}) {
|
||
for _, plugin := range pm.plugins {
|
||
plugin.Execute(data)
|
||
}
|
||
}
|
||
|
||
// 日志插件
|
||
type LoggingPlugin struct{}
|
||
|
||
func (lp *LoggingPlugin) Name() string { return "日志插件" }
|
||
func (lp *LoggingPlugin) Execute(data interface{}) error {
|
||
fmt.Printf(" [日志] %v\n", data)
|
||
return nil
|
||
}
|
||
|
||
// 缓存插件
|
||
type CachePlugin struct{}
|
||
|
||
func (cp *CachePlugin) Name() string { return "缓存插件" }
|
||
func (cp *CachePlugin) Execute(data interface{}) error {
|
||
fmt.Printf(" [缓存] 缓存数据: %v\n", data)
|
||
return nil
|
||
}
|
||
|
||
// 安全插件
|
||
type SecurityPlugin struct{}
|
||
|
||
func (sp *SecurityPlugin) Name() string { return "安全插件" }
|
||
func (sp *SecurityPlugin) Execute(data interface{}) error {
|
||
fmt.Printf(" [安全] 安全检查: %v\n", data)
|
||
return nil
|
||
}
|
||
|
||
// 数据排序器
|
||
type DataSorter struct {
|
||
data []int
|
||
strategy SortStrategy
|
||
}
|
||
|
||
func (ds *DataSorter) SetStrategy(strategy SortStrategy) {
|
||
ds.strategy = strategy
|
||
}
|
||
|
||
func (ds *DataSorter) Sort() {
|
||
if ds.strategy != nil {
|
||
ds.strategy.Sort(ds.data)
|
||
}
|
||
}
|
||
|
||
// 冒泡排序
|
||
type BubbleSort struct{}
|
||
|
||
func (bs *BubbleSort) Sort(data []int) {
|
||
n := len(data)
|
||
for i := 0; i < n-1; i++ {
|
||
for j := 0; j < n-i-1; j++ {
|
||
if data[j] > data[j+1] {
|
||
data[j], data[j+1] = data[j+1], data[j]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 快速排序
|
||
type QuickSort struct{}
|
||
|
||
func (qs *QuickSort) Sort(data []int) {
|
||
qs.quickSort(data, 0, len(data)-1)
|
||
}
|
||
|
||
func (qs *QuickSort) quickSort(data []int, low, high int) {
|
||
if low < high {
|
||
pi := qs.partition(data, low, high)
|
||
qs.quickSort(data, low, pi-1)
|
||
qs.quickSort(data, pi+1, high)
|
||
}
|
||
}
|
||
|
||
func (qs *QuickSort) partition(data []int, low, high int) int {
|
||
pivot := data[high]
|
||
i := low - 1
|
||
|
||
for j := low; j < high; j++ {
|
||
if data[j] < pivot {
|
||
i++
|
||
data[i], data[j] = data[j], data[i]
|
||
}
|
||
}
|
||
data[i+1], data[high] = data[high], data[i+1]
|
||
return i + 1
|
||
}
|
||
|
||
// 新闻机构
|
||
type NewsAgency struct {
|
||
observers []Observer
|
||
}
|
||
|
||
func (na *NewsAgency) Subscribe(observer Observer) {
|
||
na.observers = append(na.observers, observer)
|
||
}
|
||
|
||
func (na *NewsAgency) Unsubscribe(observer Observer) {
|
||
for i, obs := range na.observers {
|
||
if obs == observer {
|
||
na.observers = append(na.observers[:i], na.observers[i+1:]...)
|
||
break
|
||
}
|
||
}
|
||
}
|
||
|
||
func (na *NewsAgency) Notify(news string) {
|
||
for _, observer := range na.observers {
|
||
observer.Update(news)
|
||
}
|
||
}
|
||
|
||
func (na *NewsAgency) PublishNews(news string) {
|
||
fmt.Printf(" 发布新闻: %s\n", news)
|
||
na.Notify(news)
|
||
}
|
||
|
||
// 电视频道
|
||
type TVChannel struct {
|
||
name string
|
||
}
|
||
|
||
func (tv *TVChannel) Update(news string) {
|
||
fmt.Printf(" %s 播报: %s\n", tv.name, news)
|
||
}
|
||
|
||
// 广播电台
|
||
type RadioStation struct {
|
||
name string
|
||
}
|
||
|
||
func (rs *RadioStation) Update(news string) {
|
||
fmt.Printf(" %s 播报: %s\n", rs.name, news)
|
||
}
|
||
|
||
// 新闻网站
|
||
type NewsWebsite struct {
|
||
name string
|
||
}
|
||
|
||
func (nw *NewsWebsite) Update(news string) {
|
||
fmt.Printf(" %s 发布: %s\n", nw.name, news)
|
||
}
|
||
|
||
// 文件日志记录器
|
||
type FileLogger struct{}
|
||
|
||
func (fl FileLogger) Log(message string) {
|
||
fmt.Printf(" [文件日志] %s\n", message)
|
||
}
|
||
|
||
// 控制台日志记录器
|
||
type ConsoleLogger struct{}
|
||
|
||
func (cl ConsoleLogger) Log(message string) {
|
||
fmt.Printf(" [控制台日志] %s\n", message)
|
||
}
|
||
|
||
// 数据库日志记录器
|
||
type DatabaseLogger struct{}
|
||
|
||
func (dl DatabaseLogger) Log(message string) {
|
||
fmt.Printf(" [数据库日志] %s\n", message)
|
||
}
|
||
|
||
// 旧支付系统
|
||
type OldPaymentSystem struct{}
|
||
|
||
func (ops *OldPaymentSystem) MakePayment(amount float64) {
|
||
fmt.Printf(" 旧系统处理支付: $%.2f\n", amount)
|
||
}
|
||
|
||
// 支付适配器
|
||
type PaymentAdapter struct {
|
||
oldSystem *OldPaymentSystem
|
||
}
|
||
|
||
func (pa *PaymentAdapter) ProcessPayment(amount float64, currency string) bool {
|
||
fmt.Printf(" 适配器转换: %.2f %s\n", amount, currency)
|
||
pa.oldSystem.MakePayment(amount)
|
||
return true
|
||
}
|
||
|
||
// ========== 辅助函数 ==========
|
||
|
||
// 排序函数
|
||
func Sort(data Sortable) {
|
||
n := data.Len()
|
||
for i := 0; i < n-1; i++ {
|
||
for j := 0; j < n-i-1; j++ {
|
||
if data.Less(j+1, j) {
|
||
data.Swap(j, j+1)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 计算总面积
|
||
func calculateTotalArea(shapes []Shape) float64 {
|
||
total := 0.0
|
||
for _, shape := range shapes {
|
||
total += shape.Area()
|
||
}
|
||
return total
|
||
}
|
||
|
||
// 找出最大面积的形状
|
||
func findLargestShape(shapes []Shape) Shape {
|
||
if len(shapes) == 0 {
|
||
return nil
|
||
}
|
||
|
||
largest := shapes[0]
|
||
maxArea := largest.Area()
|
||
|
||
for _, shape := range shapes[1:] {
|
||
if area := shape.Area(); area > maxArea {
|
||
maxArea = area
|
||
largest = shape
|
||
}
|
||
}
|
||
|
||
return largest
|
||
}
|
||
|
||
// 数据库工厂函数
|
||
func createDatabase(dbType string) Database {
|
||
switch dbType {
|
||
case "mysql":
|
||
return MySQL{}
|
||
case "postgres":
|
||
return PostgreSQL{}
|
||
case "redis":
|
||
return Redis{}
|
||
default:
|
||
return MySQL{}
|
||
}
|
||
}
|
||
|
||
// 日志记录器工厂函数
|
||
func CreateLogger(loggerType string) Logger {
|
||
switch loggerType {
|
||
case "file":
|
||
return FileLogger{}
|
||
case "console":
|
||
return ConsoleLogger{}
|
||
case "database":
|
||
return DatabaseLogger{}
|
||
default:
|
||
return ConsoleLogger{}
|
||
}
|
||
}
|
||
|
||
/*
|
||
运行这个程序:
|
||
go run 01-basic-interfaces.go
|
||
|
||
学习要点:
|
||
1. 接口定义了方法签名的集合,是一种抽象类型
|
||
2. Go 语言的接口实现是隐式的,无需显式声明
|
||
3. 接口支持多态,允许不同类型以统一方式处理
|
||
4. 接口可以组合,通过嵌入其他接口实现
|
||
5. 接口是 Go 语言实现抽象和多态的核心机制
|
||
|
||
接口的特性:
|
||
1. 隐式实现:只要实现了接口的所有方法就自动实现了接口
|
||
2. 多态性:不同类型可以实现同一接口
|
||
3. 组合性:接口可以嵌入其他接口
|
||
4. 类型安全:编译时检查接口实现
|
||
5. 零值:接口的零值是 nil
|
||
|
||
接口的优势:
|
||
1. 代码解耦:依赖抽象而不是具体实现
|
||
2. 可测试性:便于编写单元测试和模拟对象
|
||
3. 可扩展性:新类型可以轻松实现现有接口
|
||
4. 多态性:统一处理不同类型的对象
|
||
5. 组合性:通过接口组合实现复杂功能
|
||
|
||
接口设计原则:
|
||
1. 接口应该小而专注(单一职责)
|
||
2. 优先定义行为而不是数据
|
||
3. 接口名通常以 -er 结尾
|
||
4. 避免过度抽象
|
||
5. 考虑接口的可组合性
|
||
|
||
常见应用场景:
|
||
1. 多态处理:统一处理不同类型
|
||
2. 依赖注入:解耦具体实现
|
||
3. 插件系统:动态加载和执行
|
||
4. 策略模式:算法的动态选择
|
||
5. 观察者模式:事件通知机制
|
||
6. 适配器模式:接口适配
|
||
7. 工厂模式:对象创建抽象
|
||
|
||
最佳实践:
|
||
1. 保持接口简单和专注
|
||
2. 优先使用小接口而不是大接口
|
||
3. 在需要的地方定义接口
|
||
4. 使用接口实现依赖倒置
|
||
5. 合理使用接口组合
|
||
6. 避免不必要的接口抽象
|
||
|
||
注意事项:
|
||
1. nil 接口不能调用方法
|
||
2. 接口类型断言需要检查成功与否
|
||
3. 接口实现是编译时检查的
|
||
4. 空接口可以持有任何类型的值
|
||
5. 接口比较需要注意动态类型和动态值
|
||
*/ |