面试题答案
一键面试设计思路
- 定义图形接口:创建一个
Shape
接口,包含Draw
方法,任何需要绘制的图形都必须实现这个接口。这样可以统一不同图形的绘制操作,方便后续使用接口来操作不同类型的图形。 - 定义具体图形结构体:分别为圆形和矩形定义结构体,例如
Circle
和Rectangle
结构体,结构体中包含图形所需的属性,如圆形的半径,矩形的长和宽等。 - 实现接口方法:让
Circle
和Rectangle
结构体实现Shape
接口的Draw
方法,在各自的Draw
方法中实现具体的绘制逻辑。
代码示例
package main
import "fmt"
// Shape 接口定义绘制方法
type Shape interface {
Draw()
}
// Circle 结构体表示圆形
type Circle struct {
Radius float64
}
// Draw 方法实现圆形的绘制逻辑
func (c Circle) Draw() {
fmt.Printf("Drawing a circle with radius %.2f\n", c.Radius)
}
// Rectangle 结构体表示矩形
type Rectangle struct {
Width float64
Height float64
}
// Draw 方法实现矩形的绘制逻辑
func (r Rectangle) Draw() {
fmt.Printf("Drawing a rectangle with width %.2f and height %.2f\n", r.Width, r.Height)
}
通过接口实现多态
在Go语言中,接口类型的变量可以持有任何实现了该接口的类型的值。可以创建一个 Shape
类型的切片,然后将 Circle
和 Rectangle
类型的实例放入切片中。遍历切片时,调用 Draw
方法,会根据实际的类型调用相应的 Draw
实现,从而实现多态。
func main() {
var shapes []Shape
shapes = append(shapes, Circle{Radius: 5.0})
shapes = append(shapes, Rectangle{Width: 10.0, Height: 5.0})
for _, shape := range shapes {
shape.Draw()
}
}
结构体组合相较于传统继承在这种场景下的优势
- 避免多重继承问题:传统继承中,多重继承可能会导致菱形继承等复杂问题,而Go语言没有继承,通过结构体组合避免了这种复杂性。
- 灵活性更高:结构体组合可以更灵活地组合不同的功能,而不是像继承那样形成固定的层次结构。例如,一个结构体可以组合多个不同的结构体来获取不同的功能,而不是局限于单一的继承链。
- 代码复用更细粒度:继承是对整个类层次的复用,而结构体组合可以选择复用特定的结构体字段和方法,实现更细粒度的代码复用。
- 降低耦合度:结构体组合使得各个组件之间的耦合度更低,修改一个结构体的实现不会影响到其他结构体,而继承中父类的修改可能会对所有子类产生影响。