2011-01-09 29 views
6

Trong C tôi có thể làm một cái gì đó như thế nàysubclassing trong google đi

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

Sử dụng phương pháp này, tôi có thể vượt qua bất kỳ struct (Circle, Rectangle, vv) có struct Point là thành viên đầu tiên. Làm cách nào để tôi có thể thực hiện tương tự trong google go?

+0

Đó là một ví dụ khá messed-up, tại sao không sử dụng: 'di chuyển (& c.p, 1, 2)' thay vì dựa vào 'bố trí bộ nhớ Circle' không? Ngoài ra, nó không quy mô cho tất cả các hình dạng, trừ khi bạn luôn luôn xác định một hình dạng từ barycenter của nó? –

+0

coz Chi tiết nội bộ của vòng tròn không được xuất. Vòng kết nối được cho là loại mờ cho khách hàng. – Nyan

Trả lời

7

Mặc dù Go có các loại và các phương pháp và cho phép một phong cách hướng đối tượng của lập trình, không có loại hệ thống cấp bậc. Khái niệm “giao diện” trong Go cung cấp một cách tiếp cận khác nhau mà chúng tôi tin rằng rất dễ sử dụng và trong một số cách tổng quát hơn là . Ngoài ra còn có các cách để nhúng các loại khác vào cung cấp một cái gì đó tương tự — nhưng không phải là giống hệt nhau — cho phân lớp phụ. Is Go an object-oriented language?, FAQ.

Ví dụ,

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

Điều này không giống như mã C. Mã Move() được nhân bản cho mọi loại ở đây ... – Nyan

+2

Câu trả lời của PeterSO là thành ngữ Go; Go không cho phép truyền con trỏ tới con trỏ khác, chỉ truyền con trỏ đến giao diện phù hợp - do đó, anh ấy đã xác định giao diện và một số loại được gắn với nó. – swdunlop

11

Trên thực tế, có một cách đơn giản hơn để làm điều đó, mà là tương tự như ví dụ của 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) 

Cũng cần chú ý rằng các mối cũng sẽ hoàn thành giao diện Mover mà PeterSO đã đăng.

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

Các vấn đề liên quan