Nyan
Nyan

Reputation: 2461

How to subclass in Go

In C I can do something like this

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);

Using this approach, I can pass any struct(Circle,Rectangle,etc) that has struct Point as first member. How can I do the same in google go?

Upvotes: 9

Views: 8588

Answers (2)

Roxy Light
Roxy Light

Reputation: 5147

Actually, there's a simpler way to do it, which is more similar to the OP's example:

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)

Also notice that Circle would also fulfill the Mover interface that PeterSO posted.

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

Upvotes: 19

peterSO
peterSO

Reputation: 166616

Although Go has types and methods and allows an object-oriented style of programming, there is no type hierarchy. The concept of “interface” in Go provides a different approach that we believe is easy to use and in some ways more general. There are also ways to embed types in other types to provide something analogous—but not identical—to subclassing. Is Go an object-oriented language?, FAQ.

For example,

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)
}

Upvotes: 8

Related Questions