@jimt가 제공 한 답변을 확장하고 싶었 습니다 . 그 대답은 정확하고 이것을 분류하는 데 엄청나게 도움이되었습니다. 그러나 문제가있는 두 가지 방법 (별명, 포함)에주의해야 할 점이 있습니다.
참고 : 나는 부모와 자식이라는 용어를 사용하지만 그것이 구성에 가장 적합한 지 확실하지 않습니다. 기본적으로 parent는 로컬에서 수정하려는 유형입니다. Child는 해당 수정을 구현하려는 새로운 유형입니다.
방법 1-유형 정의
type child parent
// or
type MyThing imported.Thing
- 필드에 대한 액세스를 제공합니다.
- 메소드에 대한 액세스를 제공하지 않습니다.
방법 2-임베딩 ( 공식 문서 )
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의 인터페이스 (및 객체 방향을 다시 생각하는 접근 방식)를 즉시 기억하고 나서이 질문이 있습니다.