2016-06-30 17 views
4

私は、次のしている:Golangメソッドのオーバーライド

type Base struct { 

} 

func(base *Base) Get() string { 
    return "base" 
} 

func(base *Base) GetName() string { 
    return base.Get() 
} 

私はBaseの代わりに新しいタイプを使用して、どこ項目GetName()ことができるように取得します()の新しい実装で新しいタイプを定義したいです新しいGet()実装を呼び出します。 Javaを使用していた場合、Baseを継承してGet()をオーバーライドします。 Goでこれをどのように達成する必要がありますか?可能であれば変更を破棄しないようにしたいので、Baseの既存の消費者を変更する必要はありません。この時

私の最初の刺し傷は動作しません..which ..

type Sub struct { 
    Base 
} 

func(sub *Sub) Get() string { 
    return "Sub" 
} 

のように見えます。私の脳はまだ明確にGoのために配線されていません。

+2

の可能な複製を[ golangの親structからオーバーライドされたメソッドを呼び出すことは可能ですか?](http:// stacko verflow.com/questions/21251242/is-it-possible-to-call-overridden-method-from-parent-struct-in-golang) – Vadyus

+1

Goには継承がなく、ジェネリックもありません。何かが 'Base'型を予期しているなら、それを別の型で与えることはできません。 – JimB

答えて

2

Goは、古典的なOO言語ではありません。クラスと継承の概念はわかりません。

しかし、オブジェクト指向の多くの側面を利用できるようにする、非常に柔軟なインターフェースの概念が含まれています。 Goのインタフェースは、オブジェクトの振る舞いを指定する方法を提供します。何かがこれを行うことができる場合は、ここで使用できます。

インターフェイスには一連のメソッドが定義されていますが、これらのメソッドにはコードが含まれていません。実装されていません(つまり、抽象メソッド)。

同じ方法で異なるタイプを使用する方法は、インターフェイスを使用することです。

package main 

import (
    "fmt" 
) 

type Base struct{} 
type Baser interface { 
    Get() float32 
} 

type TypeOne struct { 
    value float32 
    Base 
} 

type TypeTwo struct { 
    value float32 
    Base 
} 

type TypeThree struct { 
    value float32 
    Base 
} 

func (t *TypeOne) Get() float32 { 
    return t.value 
} 

func (t *TypeTwo) Get() float32 { 
    return t.value * t.value 
} 

func (t *TypeThree) Get() float32 { 
    return t.value + t.value 
} 

func main() { 
    base := Base{} 
    t1 := &TypeOne{1, base} 
    t2 := &TypeTwo{2, base} 
    t3 := &TypeThree{4, base} 

    bases := []Baser{Baser(t1), Baser(t2), Baser(t3)} 

    for s, _ := range bases { 
     switch bases[s].(type) { 
     case *TypeOne: 
      fmt.Println("TypeOne") 
     case *TypeTwo: 
      fmt.Println("TypeTwo") 
     case *TypeThree: 
      fmt.Println("TypeThree") 
     } 

     fmt.Printf("The value is: %f\n", bases[s].Get()) 
    } 
} 

Go Playground

+5

私はこれが質問に答えるとは思わない。彼はサブクラスをインスタンス化し、GetNameを呼び出し、実際に呼び出されたサブクラスメソッドを持っていました。この例はそれに取り組もうとしていません。 –

1

インターフェースはメソッドのシグネチャのコレクションを命名されています:
参照:https://gobyexample.com/interfaces
と:http://www.golangbootcamp.com/book/interfaces
ので、それがない方が良いです。ここ

は、それを証明するために簡単な例でありますそのようなOOP方法で使用する。


何を慣用的 が、可能(2ウェイ)Golangされていません問う:

package main 

import "fmt" 

type Base struct { 
} 

func (base *Base) Get() string { 
    return "base" 
} 

type Getter interface { 
    Get() string 
} 

func (base *Base) GetName(getter Getter) string { 
    if g, ok := getter.(Getter); ok { 
     return g.Get() 
    } else { 
     return base.Get() 
    } 
} 

// user code : 
type Sub struct { 
    Base 
} 

func (t *Sub) Get() string { 
    return "Sub" 
} 
func (t *Sub) GetName() string { 
    return t.Base.GetName(t) 
} 

func main() { 
    userType := Sub{} 
    fmt.Println(userType.GetName()) // user string 
} 

出力:

これはあなたが(ワーキングサンプルコード)を必要とするものである

ユーザーコードで1つの初期化コードを実行する必要があります。

func (t *Sub) GetName() string { 
    return t.Base.GetName(t) 
} 

も、この作品:

package main 

import "fmt" 

type Getter interface { 
    Get() string 
} 

type Base struct { 
    Getter 
} 

func (base *Base) Get() string { 
    return "base" 
} 

func (base *Base) GetName() string { 
    return base.Getter.Get() 
} 

// user code : 
type Sub struct { 
    Base 
} 

func (t *Sub) Get() string { 
    return "Sub" 
} 
func New() *Sub { 
    userType := &Sub{} 
    userType.Getter = interface{}(userType).(Getter) 
    return userType 
} 

func main() { 
    userType := New() 
    fmt.Println(userType.GetName()) // user string 
} 

出力:

を使用すると、1つの初期化コードは、ユーザーコード内で行う必要があります参照よう:

userType.Getter = interface{}(userType).(Getter) 
関連する問題