已有7847人阅读此文 - - 未分类 - luoyy -
No.1 问题
首先我们看一下常规的struct继承使用
package main
import (
"fmt"
)
type TestA struct {
}
func (a *TestA) CallA() {
a.Test()
}
func (a *TestA) Test() {
fmt.Println("Out TestA")
}
type TestB struct {
TestA
}
func (b *TestB) Test() {
fmt.Println("Out TestB")
}
func (b *TestB) CallB() {
b.Test()
}
func main() {
test := &TestB{}
test.CallA() // Out TestA
test.CallB() // Out TestB
}
正如上述的代码,输出的结果,test.CallA()
输出 "Out TestA",test.CallB()
输出 "Out TestB",此时并未与我们所知的其它面向对象语言(Java, PHP, Javascript等等)的输出结果。
No.2 如何解决
其实对于自上而下的继承层次结构中,子类对于父类的属性和方法都是可以调用与修改(具有Public权限时)的,我们则可以利用该特点:
package main
import (
"fmt"
)
type TestA struct {
testMethod func() // 我们可以在父级struct中定义一个可以供访问与修改的属性,期类型为一个func().(此处小写,具有包内可访问权限)
}
func (a *TestA) CallA() {
a.Test()
}
func (a *TestA) test() {
fmt.Println("Out TestA")
}
func (a *TestA) Test() {
a.testMethod()
}
type TestB struct {
TestA
}
func (b *TestB) test() {
fmt.Println("Out TestB")
}
func (b *TestB) CallB() {
b.Test()
}
func main() {
test := &TestB{}
test.testMethod = test.test // 修改testMethod
test.CallA() // Out TestB
test.CallB() // Out TestB
}
这样我们就能实现一些特殊的需求比如说在父类调用子类的方法。
Next:
package main
import (
"fmt"
)
type Implements[T any] interface {
Prototype(T)
Proto() T
}
type Extends[T any] struct {
_proto_ T
}
func (e *Extends[T]) Prototype(_proto_ T) {
e._proto_ = _proto_
}
func (e *Extends[T]) Proto() T {
return e._proto_
}
type TestInterface interface {
Implements[TestInterface]
Out() string
F() string
Foo() string
}
type Test struct {
Extends[TestInterface]
}
func (t *Test) Out() string {
return t.Proto().F() + ":" + t.Foo()
}
func (t *Test) F() string {
return "Test F"
}
func (t *Test) Foo() string {
return "Test Foo"
}
type AInterface interface {
TestInterface
}
type A struct {
Test
}
func MakeA() *A {
s := &A{}
s.Prototype(s)
return s
}
func NewA() *A {
s := MakeA()
s.Construct()
return s
}
func (a *A) Construct() {
}
func (a *A) F() string {
return "A F" + ":" + a.Test.F()
}
func (a *A) Foo() string {
return "A Foo"
}
func main() {
a := NewA()
fmt.Println(a.Out())
}
这样比较完美