多型

2016-05-16 20 views
1

だから、私の質問は:それはすることが可能です出力を参照してください多型

im in A 
im in B 

Bの発見?

func (obj B) Discover() string { 
    return obj.GetTest() 
} 

なぜですか?

(クラス)各構造体に行く遊び場を発見して貼り付け https://play.golang.org/p/nYc2hc3UbG

おかげで私はすべての構造体のためにかなり同じ小さな(クラスなど)構造体のメソッドと発見がたくさんきたので、私はコピー&を避けたいです前進!

+1

Goには継承はなく(ポリモーフィズムもありません)、いくつかの関連する/可能な重複:[1](http:// stackoverflow。(2)(http://stackoverflow.com/questions/30622605/can-embedded)を参照してください。[2](http://stackoverflow.com/questions/30622605/can-embedded親子関係の知識を持つ)、[3](http://stackoverflow.com/questions/29390736/go-embedded-struct-call-child-method-instead-parent-method) 、[4](http://stackoverflow.com/questions/29144622/what-is-the-idiomatic-way-in-go-to-create-a-complex-hierarchy-of-structs)を参照してください。 – icza

答えて

7

いいえABに埋め込んでいます。 BにはDiscoverの定義がないため、Aのバージョンが常に呼び出されます。その方法は、タイプAAの受信者は、Bという認識を持たないか、それがBに組み込まれているという事実がありません。したがって、Aはそれ自身のバージョンのGetTest()としか呼べません。

Bが発見インターフェイスを満たす唯一の理由は、Aが埋め込まれているためです。それは間接的にそれを実装します。 Bに機能を追加する場合は、Bに定義する必要があります。これはまったく多型ではなく、構成です。 BAではなく、BAです。多相性が必要な場合は、インターフェースを使用して実装します。 Bは検出可能ですが、Aがあるためです。

私はこれが例のためのものだと考えていますが、このDiscoveryメソッドを実際に持っている理由は全くありません。あなたのインターフェイスは、代わりにGetTestが必要です。埋め込みと継承を混同しないでください。 Goには継承はありません。埋め込み型と組み込み型の間の関係が継承の1つではないため、インターフェイスを実装することで多態性の動作を実現し、コーナーをカットすることはできません。基本クラスまたは "上書き"はありません。

+0

これは私が実装しようとしていることですが、あなたが私がGOでこれをどうやってできるか教えてもらえますか? https://play.golang.org/p/sqF9nxQBBW オブジェクトを返すクラスファクトリは、ユーザの入力に依存します(設定ファイルは本当にあります)。その後、構造体myStructを埋め込み、データベースに保存する必要があります。 –

1

@ evanmcdonnalのポイントに追加すると、埋め込みは継承も多相もありません。継承はちょうどあなたが自由のためのインタフェースの実装を得るかもしれないような利便性であるが、その明示的なGoで起こる。 @evanmcdonnalが指摘したように、埋め込みは継承のように見えるかもしれませんが、そうではありません。

代わりに、多相性の概念を継承と埋め込みと継承から分離する必要があります。この比較は、ほとんどのオブジェクト指向言語から継承されません。一例として、以下は多型の実装である。 Discoverがインターフェイスをとり、ABがインターフェイスを実装していることに注目してください。

package main 

import "fmt" 

type A struct{} 
type B struct{} 

type Test interface{ 
    GetTest() string 
} 

func (a *A) GetTest() string { 
    return "i am in A" 
} 

func (b *B) GetTest() string { 
    return "i am in B" 
} 

func Discover(t Test) string { 
    return t.GetTest() 
} 

func main() { 
    a := &A{} 
    b := &B{} 

    fmt.Println(Discover(a)) 
    fmt.Println(Discover(b)) 
} 
+0

@evanmcdonnalの答えでコメントを探してください、私がしようとしているものがあります。 –

+2

コードで 'BaseClass'や' DerivedClass'のような名前の使用を控えます。 Goにはクラスや継承といったものがないので、はるかに混乱します。異なる 'GetValue'メソッドの実装を壊した場合、それらでより大きな' struct'を構成することができます。これは、あなたが望む行動を模倣できる1つの方法です。 –