如何在Go中进行子类化

huangapple go评论73阅读模式
英文:

How to subclass in Go

问题

在Go语言中,可以使用嵌入结构体的方式实现类似的功能。

type Point struct {
    x, y int
}

type Circle struct {
    Point     // 嵌入Point结构体
    rad   int
}

func move(p *Point, dx, dy int) {
    // ...
}

var c Circle
move(&c.Point, 1, 2)

使用这种方法,可以传递任何以Point结构体作为第一个成员的结构体(如Circle、Rectangle等)。

英文:

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?

答案1

得分: 19

实际上,有一种更简单的方法可以做到这一点,更类似于OP的示例:

type Point struct {
	x, y int
}

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

type Circle struct {
	*Point // 在Circle中嵌入Point
	rad int
}

// Circle现在隐式地具有"Move"方法
c := &Circle{&Point{0, 0}, 5}
c.Move(7, 3)

还要注意,Circle也将满足PeterSO发布的Mover接口。

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

英文:

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

答案2

得分: 8

尽管Go具有类型和方法,并且允许面向对象的编程风格,但它没有类型层次结构。Go中的“接口”概念提供了一种不同的方法,我们认为这种方法易于使用,并且在某些方面更加通用。还有一些方法可以将类型嵌入到其他类型中,以提供类似但不完全相同的子类化功能。Go是一种面向对象的语言吗?,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)
}
英文:

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

huangapple
  • 本文由 发表于 2011年1月10日 00:56:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/4640397.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定