golang的遗传和多态性是可能的吗?

bnl4lu3b  于 2023-02-06  发布在  Go
关注(0)|答案(1)|浏览(111)

这个问题来自于我不得不做的从C++程序的工作逻辑到golang上下文的移植。这只是一个例子,我看到它是多么的不可思议,但是想想它背后的逻辑。如果解释让你厌烦,去代码,它是非常自我解释的。否则我会尝试解释。概念是我有一个基类,它包含了一个具有公共逻辑的方法。但该方法使用虚函数,每个后代都需要实现虚函数。
在Go语言中,我很容易实现基方法的继承,但是对后代的多态适应(对我来说)很复杂:我不知道如何复制这种机制。

class TPolygon{

private:
    int nside;

public:
    TPolygon(int n){ nside=n; }
    virtual float Area()=0;
    float MeanArea(){ return Area()/nside; }
};

class TSquare: public TPolygon{

private:
    float side;

public:
    TSquare(float sidelen):TPolygon(4){ side=sidelen; }
    float Area(){ return side*side; }
};

class TTriangle: public TPolygon{

private:
    float base, height;

public:
    TTriangle(float b, float h):TPolygon(3){ base=b; height=h; }
    float Area(){ return base*height/2; }
};

TSquare *square=new TSquare(2.0);
square->MeanArea(); // -> 2*2 / 4 correct

TTriangle *triangle=new TTriangle(5.0, 6.0);
triangle->MeanArea(); // -> 5*6/2 / 3 correct

在围棋中我试过:

type TPolygon struct {
    nside int
}

func (p *TPolygon) Area() float64 {
    return 0
}

func (p *TPolygon) MeanArea() float64 {
    return p.Area() / float64(p.nside)
}

type TSquare struct {
    TPolygon

    side float64
}

func NewSquare(sidelength float64) *TSquare {

    return &TSquare{
        TPolygon: TPolygon{nside: 4},

        side: sidelength,
    }
}

func (s *TSquare) Area() float64 {
    return s.side * s.side
}

type TTriangle struct {
    TPolygon

    base, height float64
}

func NewTriangle(b, h float64) *TTriangle {

    return &TTriangle{
        TPolygon: TPolygon{nside: 3},

        base:   b,
        height: h,
    }
}

func (t *TTriangle) Area() float64 {
    return t.base * t.height / 2
}

square := NewSquare(2.0)
square.MeanArea() // -> 0 from TPolygon.Area()

我发现实现这一点的唯一方法是一个打破DRY原则的变通方案,因为需要在每个后代中重复相同的方法

func (p *TPolygon) meanArea2(a float64) float64 {
    return a / float64(p.nside)
}
func (s *TSquare) MeanArea2() float64 {
    return s.meanArea2(s.Area())
}
func (t *TTriangle) MeanArea2() float64 {
    return t.meanArea2(t.Area())
}

square.MeanArea2() // -> 1 as expected

而且,如果逻辑变得更复杂,这种重构方式并不总是容易和可能的。有人知道这种架构在golang是否可行,以及如何实现吗?或者是否有其他接近的解决方案?

pnwntuvh

pnwntuvh1#

有很多方法可以模拟继承,但下面的方法要简洁得多,它允许计算实现这两个方法的任何类型的area/nsides值:

type MeanAreaSupport interface {
   NSides() int
   Area() float64
}

func MeanArea(shape MeanAreaSupport) float64 {
   return shape.Area()/shape.NSides()
}

相关问题