0
已有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())
}

这样比较完美

期待你一针见血的评论,Come on!

发表评论: