如何在Go中继承

时间:2011-01-09 16:56:22

标签: oop go

在C中我可以做这样的事情

struct Point {
  int x,y;
}

struct Circle {
  struct Point p;       // must be first!
  int rad;
}

void move(struct Point *p,int dx,int dy) {
    ....
}

struct Circle c = .....;
move( (struct Point*)&c,1,2);

使用这种方法,我可以传递任何具有struct Point作为第一个成员的结构(Circle,Rectangle等)。 我怎样才能在google go中做同样的事情?

2 个答案:

答案 0 :(得分:13)

实际上,有一种更简单的方法可以做到这一点,这与OP的例子更相似:

type Point struct {
    x, y int
}

func (p *Point) Move(dx, dy int) {
    p.x += dx
    p.y += dy
}

type Circle struct {
    *Point // embedding Point in Circle
    rad int
}

// Circle now implicitly has the "Move" method
c := &Circle{&Point{0, 0}, 5}
c.Move(7, 3)

另请注意,Circle还将实现PeterSO发布的Mover界面。

http://golang.org/doc/effective_go.html#embedding

答案 1 :(得分:7)

  

虽然Go有类型和方法   允许面向对象的风格   编程,没有类型   层次结构。 “界面”的概念   在Go中提供了一种不同的方法   我们相信这很容易使用   一些方面更一般。还有   将类型嵌入其他类型的方法   提供类似的东西 - 但不是   相同的子类化。 Is Go an object-oriented language?, FAQ.

例如,

package main

import "fmt"

type Mover interface {
    Move(x, y int)
}

type Point struct {
    x, y int
}

type Circle struct {
    point Point
    rad   int
}

func (c *Circle) Move(x, y int) {
    c.point.x = x
    c.point.y = y
}

type Square struct {
    diagonal int
    point    Point
}

func (s *Square) Move(x, y int) {
    s.point.x = x
    s.point.y = y
}

func main() {
    var m Mover
    m = &Circle{point: Point{1, 2}}
    m.Move(3, 4)
    fmt.Println(m)
    m = &Square{3, Point{1, 2}}
    m.Move(4, 5)
    fmt.Println(m)
}