1. 别名
    type 不只是定义别名, 而是定义了一个新类型,所以两个类型是不能直接赋值的,要经过转换
    不会继承原类型的方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //type newtypename oldtypename

    type name string
    type age int
    var n name = "sdf"
    var s string = "wqerwr"
    //n = s 会报错
    fmt.Println(n, s)//sdf wqerwr
    n = name(s)
    fmt.Println(n, s)//wqerwr wqerwr

    还有一种是 go1.9 新加入的 类型别名,比原始写法多了个=,这种写法可以继承原类型的方法,不过想扩展原类型必须在一个包内

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    //type newtypename = oldtypename
    type MyTree = Node

    func (tree *MyTree) FirstTraverse() {
    if tree == nil {
    return
    }
    tree.Print()
    if tree.Left != nil {
    left := MyTree(*tree.Left)
    left.FirstTraverse()
    }

    if tree.Right != nil {
    right := MyTree(*tree.Right)
    right.FirstTraverse()
    }
    }
  2. 组合

    两种写法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    type myTree struct {
    node *Node
    }

    func (tree *myTree) lasttraverse() {
    if tree.node == nil{
    return
    }

    left ,right := &myTree{tree.node.Left},&myTree{tree.node.Right}
    left.lasttraverse()
    right.lasttraverse()
    tree.node.Print()
    }

    匿名写法

    可以通过类名来访问匿名成员

    一个类型的匿名成员只能有一个

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    type myTreeComb struct {
    *structs.Node
    }

    func (tree *myTreeComb) lastTraverse() {
    if tree.Node == nil {
    return
    }
    left := &myTreeComb{tree.Node.Left}
    right := &myTreeComb{tree.Right}
    left.lastTraverse()
    right.lastTraverse()
    tree.Print()

    }

    继承规则:

    在子类没有改写父类的成员方法时,相应的成员方法被继承。

    子类可以直接调用父类的成员方法,eg:基类有个成员方法为Base.Func(),那么Derived.Func()等同于Derived.Base.Func()

    如果子类方法名与父类相同,父类方法被隐藏,可以通过 Derived.Base.Func()显式调用