我一直在思考这个特定的问题,我有一种应该以最干净的方式解决它的方法。
想象一个看起来像这样的应用程序:
type AreaCalculator interface {
Area() int
}
type Rectangle struct {
color string
width int
height int
}
type (r *Rectangle) Area() int {
return r.width * r.height
}
type Circle struct {
color string
diameter int
}
type (c *Circle) Area() int {
return r.diameter / 2 * r.diameter / 2 * π
}
type Canvas struct {
children []AreaCalculator
}
func (c *Canvas) String() {
for child := range c.children {
fmt.Println("Area of child with color ", child.color, " ", child.Area())
}
}
该示例显然无法编译,因为尽管Canvas的String()方法可以调用c.Area(),但由于无法确保实现AreaCalculator的结构具有该属性,因此它无法访问c.color。
我能想到的一种解决方案是这样做:
type AreaCalculator interface {
Area() int
Color() string
}
type Rectangle struct {
color string
width int
height int
}
type (r *Rectangle) Color() string {
return r.color
}
type (r *Rectangle) Area() int {
return r.width * r.height
}
type Circle struct {
color string
diameter int
}
type (c *Circle) Area() int {
return r.diameter / 2 * r.diameter / 2 * π
}
type (c *Circle) Color() string {
return c.color
}
type Canvas struct {
children []AreaCalculator
}
func (c *Canvas) String() {
for child := range c.children {
fmt.Println("Area of child with color ", child.Color(), " ", child.Area())
}
}
另一种方法是尝试这样的事情:
type Shape struct {
Area func() int
color string
diameter int
width int
height int
}
func NewCircle() Shape {
// Shape initialisation to represent a Circle. Setting Area func here
}
func NewRectangle() Shape {
// Shape initialisation to represent a Rectangle. Setting Area func here
}
type Canvas struct {
children []Shape
}
func (c *Canvas) String() {
for child := range c.children {
fmt.Println("Area of child with color", child.color, " ", child.Area())
}
}
这些选项对我来说似乎都不干净。我敢肯定,有一种我无法想到的更清洁的解决方案。
重要的出发点是您不应模仿Go中的继承。Go没有继承。它具有接口并且具有嵌入。他们没有忘记包括继承。它不是语言的一部分。Go鼓励作文。
您的Canvas
需求不只是一个AreaCalculator
。它需要提供颜色的东西。您需要表达这一点。例如,您可以这样做:
type DrawableShape interface {
AreaCalculator
Color() string
}
然后你会实现Color()
的Rectangle
和Circle
。
func (r Rectangle) Color() string {
return r.color
}
func (c Circle) Color() string {
return c.color
}
并且children
将是[]DrawableShape
:
children []DrawableShape
这将使像这样(建筑穆罕默德Nasirifar的代码关闭)。
package main
import (
"fmt"
"math"
"strings"
)
type AreaCalculator interface {
Area() int
}
type DrawableShape interface {
AreaCalculator
Color() string
}
type Rectangle struct {
color string
width int
height int
}
func (r Rectangle) Area() int {
return r.width * r.height
}
func (r Rectangle) Color() string {
return r.color
}
type Circle struct {
color string
diameter int
}
func (c Circle) Area() int {
area := math.Round(float64(c.diameter*c.diameter) * math.Pi / float64(4))
return int(area)
}
func (c Circle) Color() string {
return c.color
}
type Canvas struct {
children []DrawableShape
}
func (c Canvas) String() string {
lines := make([]string, 0)
for _, child := range c.children {
lines = append(lines, fmt.Sprintf("Area of child with color %s %d", child.Color(), child.Area()))
}
return strings.Join(lines, "\n")
}
func main() {
circle := &Circle{color: "red", diameter: 2}
rect := &Rectangle{color: "blue", width: 3, height: 4}
canvas := &Canvas{
children: []DrawableShape{circle, rect},
}
fmt.Println(canvas.String())
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句