2015-04-18 1 views
1

Код внедренной структуры в hereВ golang, Как я могу переопределить метод

package main 

import "fmt" 

func main() { 
    t16() 
} 

type Base struct { 
    val int 
} 
func (b *Base)Set(i int) { 
    b.val = i 
} 
type Sub struct { 
    Base 
    changed bool 
} 

func (b *Sub)Set(i int) { 
    b.val = i 
    b.changed = true 
} 
func t16() { 
    s := &Sub{} 
    s.Base.Set(1) 
    var b *Base = &s.Base 
    fmt.Printf("%+v\n", b) 
    fmt.Printf("%+v\n", s) 
} 

Я хочу сделать Sub выступать в качестве базы, но когда я звоню Set, для Sub это будет означать changed.I знаю, что есть нет полиморфизма или прокси в голанге, но есть ли способ сделать это, а не влиять на базу?

ОБНОВЛЕНО

Я надеюсь, что, когда я называю Base.Set это будет означать изменение, для пользователя, они не знают, что они на самом деле использовать Sub, так что я могу контролировать Базовый себя весть.

func t16() { 
    s := &Sub{} 
    var b *Base = &s.Base 
    b.Set(10) 
    fmt.Printf("%+v\n", b) 
    fmt.Printf("%+v\n", s) 
} 

ответ

0

Я думаю, что я должен использовать интерфейс здесь, это добиться того, чего я хочу, но повлияло на базу

func main() { 
    t16() 
} 

type Base interface { 
    Set(int) 
} 
type base struct { 
    val int 
} 
func (b *base)Set(i int) { 
    b.val = i 
} 
type Sub struct { 
    base 
    changed bool 
} 

func (b *Sub)Set(i int) { 
    b.val = i 
    b.changed = true 
} 
func t16() { 
    s := &Sub{} 
    s.Set(1) 
    var b Base = s 
    fmt.Printf("%+v\n", b) 
    fmt.Printf("%+v\n", s) 
} 
4

Имея Sub встраивать Base он автоматически имеет все области Base «s и функций из доступны в качестве членов верхнего уровня Sub. Это означает, что вы можете напрямую позвонить s.val, и вы бы быть в состоянии назвать s.Set вызвать базовую функцию кроме тот факт, что Sub реализован свой собственный метод, который Setскрывающую Базу один.

Когда вы вызываете s.Base.Set() в своем примере, вы обходите Sub.Set() и напрямую звоните Base.Set().

Чтобы исправить это в вашем случае так же просто, как позвонить s.Set() вместо s.Base.Set().

Это работает для меня:

func (b *Sub)Set(i int) { 
    b.Base.Set(i) 
    b.changed = true 
} 
func t16() { 
    s := &Sub{} 
    s.Set(1) 
    var b *Base = &s.Base 
    fmt.Printf("%+v\n", b) 
    fmt.Printf("%+v\n", s) 
} 

Play link

Обратите внимание, что Sub.Set() может вызвать встроенный метод структур, а также, что чувствует себя очень похоже на наследование super() типа, что и другие языки О.О. предоставляют.

+0

Если это так, то вы правы, интерфейсы - это путь. Go не имеет наследования типа 'is-a'. – captncraig