This commit is contained in:
2026-03-14 19:03:12 +08:00
parent 2805379586
commit 6d86d62825
34 changed files with 3213 additions and 0 deletions
+74
View File
@@ -0,0 +1,74 @@
# 01-interfaces - 接口定义与实现
## 知识点讲解
### 接口定义
```go
type Shape interface {
Area() float64
Perimeter() float64
}
```
### 接口实现
```go
type Rectangle struct {
Width float64
Height float64
}
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
func (r Rectangle) Perimeter() float64 {
return 2 * (r.Width + r.Height)
}
```
**注意**:Go中接口是隐式实现的,不需要显式声明
### 多态
```go
func printShapeInfo(s Shape) {
fmt.Printf("面积: %.2f\n", s.Area())
fmt.Printf("周长: %.2f\n", s.Perimeter())
}
rect := Rectangle{Width: 10, Height: 5}
circle := Circle{Radius: 7}
printShapeInfo(rect) // 可以传递Rectangle
printShapeInfo(circle) // 也可以传递Circle
```
### 空接口
```go
var any interface{}
any = 10
any = "hello"
any = []int{1, 2, 3}
```
### 重要提示
- 接口定义一组方法签名
- 任何类型只要实现了接口的所有方法,就自动实现了该接口
- 空接口 `interface{}` 可以持有任何类型的值
- 接口类型可以包含零个或多个方法
## 学习目标
完成本练习后,你将:
- ✅ 掌握接口的定义方式
- ✅ 学会实现接口
- ✅ 理解多态的概念
- ✅ 了解空接口的用法
## 练习说明
打开 `main.go`,根据注释提示填充代码,完成后运行 `go test -v` 验证答案。
+155
View File
@@ -0,0 +1,155 @@
package main
import (
"fmt"
"math"
)
type Shape interface {
Area() float64
Perimeter() float64
}
type Rectangle struct {
Width float64
Height float64
}
type Circle struct {
Radius float64
}
func (r Rectangle) Area() float64 {
return ____
}
func (r Rectangle) Perimeter() float64 {
return ____
}
func (c Circle) Area() float64 {
return math.Pi * ____ * ____
}
func (c Circle) Perimeter() float64 {
return 2 * math.Pi * ____
}
type ShapePrinter interface {
PrintInfo()
}
func (r Rectangle) PrintInfo() {
fmt.Printf("矩形 - 宽: %.2f, 高: %.2f\n", ____, ____)
}
func (c Circle) PrintInfo() {
fmt.Printf("圆形 - 半径: %.2f\n", ____)
}
func exercise1() float64 {
fmt.Println("=== 练习1:矩形接口实现 ===")
rect := Rectangle{Width: 10, Height: 5}
area := ____
perimeter := ____
fmt.Printf("矩形面积: %.2f, 周长: %.2f\n", area, perimeter)
return ____
}
func exercise2() string {
fmt.Println("=== 练习2:圆形接口实现 ===")
circle := Circle{Radius: 7}
area := ____
info := fmt.Sprintf("圆形面积: %.2f", area)
fmt.Println(____)
return ____
}
func exercise3() string {
fmt.Println("=== 练习3:多态 ===")
// 定义一个Shape类型的变量,分别指向Rectangle和Circle
var s Shape
s = ____
fmt.Printf("形状类型: %T, 面积: %.2f\n", s, s.____())
s = ____
fmt.Printf("形状类型: %T, 面积: %.2f\n", s, s.____())
return "多态演示完成"
}
func exercise4() interface{} {
fmt.Println("=== 练习4:空接口 ===")
// 空接口可以持有任何类型
var data interface{}
data = ____
fmt.Printf("数据: %v, 类型: %T\n", data, data)
data = ____
fmt.Printf("数据: %v, 类型: %T\n", data, data)
data = ____
fmt.Printf("数据: %v, 类型: %T\n", data, data)
return ____
}
type Animal interface {
Sound() string
}
type Dog struct{}
func (d Dog) Sound() string {
return "汪汪"
}
type Cat struct{}
func (c Cat) Sound() string {
return ____
}
func exercise5() string {
fmt.Println("=== 练习5:接口组合与使用 ===")
// 创建Animal切片,包含不同的动物
animals := []Animal{____, ____}
for _, animal := range ____ {
fmt.Printf("动物发出的声音: %s\n", animal.____())
}
return "动物接口演示完成"
}
func main() {
fmt.Println("=== 接口 练习 ===\n")
result1 := exercise1()
fmt.Printf("练习1结果: %.2f\n", result1)
result2 := exercise2()
fmt.Printf("练习2结果: %s\n", result2)
result3 := exercise3()
fmt.Printf("练习3结果: %s\n", result3)
result4 := exercise4()
fmt.Printf("练习4结果: %v (类型: %T)\n", result4, result4)
result5 := exercise5()
fmt.Printf("练习5结果: %s\n", result5)
}
+77
View File
@@ -0,0 +1,77 @@
package main
import (
"bytes"
"os"
"strings"
"testing"
)
func captureOutput(f func()) string {
old := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
f()
w.Close()
os.Stdout = old
var buf bytes.Buffer
buf.ReadFrom(r)
return buf.String()
}
func TestExercise1(t *testing.T) {
result := exercise1()
if result != 50 {
t.Errorf("期望 50, 实际: %f", result)
}
}
func TestExercise2(t *testing.T) {
result := exercise2()
if !strings.Contains(result, "圆形面积:") {
t.Errorf("期望包含 '圆形面积:', 实际: %s", result)
}
}
func TestExercise3(t *testing.T) {
result := exercise3()
if result != "多态演示完成" {
t.Errorf("期望 '多态演示完成', 实际: %s", result)
}
}
func TestExercise4(t *testing.T) {
result := exercise4()
if result == nil {
t.Error("期望非nil值")
}
}
func TestExercise5(t *testing.T) {
result := exercise5()
if result != "动物接口演示完成" {
t.Errorf("期望 '动物接口演示完成', 实际: %s", result)
}
}
func TestMainFunction(t *testing.T) {
output := captureOutput(main)
requiredSections := []string{
"=== 接口 练习 ===",
"练习1:矩形接口实现",
"练习2:圆形接口实现",
"练习3:多态",
"练习4:空接口",
"练习5:接口组合与使用",
}
for _, section := range requiredSections {
if !strings.Contains(output, section) {
t.Errorf("期望输出包含 '%s'", section)
}
}
}