@jimtの回答をここで詳しく説明します。その答えは正解であり、これを整理するのに非常に役立ちました。ただし、両方の方法(エイリアス、埋め込み)にはいくつかの注意点があり、問題がありました。
注:親と子という用語を使用していますが、それが作曲に最適かどうかはわかりません。基本的に、親はローカルで変更するタイプです。子は、その変更を実装しようとする新しいタイプです。
方法1-タイプの定義
type child parent
// or
type MyThing imported.Thing
- フィールドへのアクセスを提供します。
- メソッドへのアクセスを提供しません。
type child struct {
parent
}
// or with import and pointer
type MyThing struct {
*imported.Thing
}
- フィールドへのアクセスを提供します。
- メソッドへのアクセスを提供します。
- 初期化には考慮が必要です。
概要
- 組版メソッドを使用すると、埋め込まれた親がポインターの場合、初期化されません。親は個別に初期化する必要があります。
- 埋め込まれた親がポインターであり、子が初期化されたときに初期化されていない場合、nilポインター逆参照エラーが発生します。
- タイプ定義と埋め込みケースの両方で、親のフィールドにアクセスできます。
- 型定義では、親のメソッドへのアクセスは許可されていませんが、親の埋め込みは許可されています。
これは次のコードで確認できます。
遊び場での作業例
package main
import (
"fmt"
)
type parent struct {
attr string
}
type childAlias parent
type childObjParent struct {
parent
}
type childPointerParent struct {
*parent
}
func (p *parent) parentDo(s string) { fmt.Println(s) }
func (c *childAlias) childAliasDo(s string) { fmt.Println(s) }
func (c *childObjParent) childObjParentDo(s string) { fmt.Println(s) }
func (c *childPointerParent) childPointerParentDo(s string) { fmt.Println(s) }
func main() {
p := &parent{"pAttr"}
c1 := &childAlias{"cAliasAttr"}
c2 := &childObjParent{}
// When the parent is a pointer it must be initialized.
// Otherwise, we get a nil pointer error when trying to set the attr.
c3 := &childPointerParent{}
c4 := &childPointerParent{&parent{}}
c2.attr = "cObjParentAttr"
// c3.attr = "cPointerParentAttr" // NOGO nil pointer dereference
c4.attr = "cPointerParentAttr"
// CAN do because we inherit parent's fields
fmt.Println(p.attr)
fmt.Println(c1.attr)
fmt.Println(c2.attr)
fmt.Println(c4.attr)
p.parentDo("called parentDo on parent")
c1.childAliasDo("called childAliasDo on ChildAlias")
c2.childObjParentDo("called childObjParentDo on ChildObjParent")
c3.childPointerParentDo("called childPointerParentDo on ChildPointerParent")
c4.childPointerParentDo("called childPointerParentDo on ChildPointerParent")
// CANNOT do because we don't inherit parent's methods
// c1.parentDo("called parentDo on childAlias") // NOGO c1.parentDo undefined
// CAN do because we inherit the parent's methods
c2.parentDo("called parentDo on childObjParent")
c3.parentDo("called parentDo on childPointerParent")
c4.parentDo("called parentDo on childPointerParent")
}
“extension methods are not object-oriented”
C#の非オブジェクト指向()と見なされますが、今日それらを見ると、すぐにGoのインターフェイス(およびオブジェクト指向を再考するためのアプローチ)を思い出し、それからこの質問に答えました。