go 的继承

187 阅读2分钟

结论

go里没有继承只有组合.

组合中变量的覆盖

组合中新定义的变量可以覆盖之前的变量

package main

import "fmt"

// AnimalCategory 代表动物分类学中的基本分类法。
type AnimalCategory struct {
	kingdom string // 界。
	phylum  string // 门。
	class   string // 纲。
	order   string // 目。
	family  string // 科。
	genus   string // 属。
	species string // 种。
}

type Animal struct {
	scientificName string
	species        string
	AnimalCategory
}

func (ac AnimalCategory) String() string {
	return fmt.Sprintf("%s%s%s%s%s%s%s",
		ac.kingdom, ac.phylum, ac.class, ac.order,
		ac.family, ac.genus, ac.species)
}

func main() {
	//category := AnimalCategory{species: "cat",genus: "big cat"}
	//fmt.Printf("The animal category: %s\n",category)
	animal := Animal{
		scientificName: "ccat",
		species:        "new cat",
		AnimalCategory: AnimalCategory{species: "cat", kingdom: "animal"},
	}
	fmt.Printf("%s\n", animal.kingdom)
	fmt.Printf("%s\n", animal.AnimalCategory.kingdom)
	fmt.Printf("%s\n", animal.species)
	fmt.Printf("%s\n", animal.AnimalCategory.species)
	fmt.Printf("%s\n", animal)
}

输出:

animal
animal
new cat
cat
animalcat

组合中方法的覆盖关系

结果说明:

  1. 组合结构的方法会覆盖掉之前的方法,方法签名只看方法名,不关心参数和返回值
  2. 没有实现String()方法调用父级的String()方法,实现了错误的String()方法,可以通过方法名称调换用,隐式调用会使用默认的String()方法.见最后一段
package main

import "fmt"

// AnimalCategory 代表动物分类学中的基本分类法。
type AnimalCategory struct {
	kingdom string // 界。
	phylum  string // 门。
	class   string // 纲。
	order   string // 目。
	family  string // 科。
	genus   string // 属。
	species string // 种。
}

type Animal struct {
	scientificName string
	species        string
	AnimalCategory
}

func (a Animal) Category() string {
	return a.AnimalCategory.String()
}

func (a Animal) String() int {
	//return fmt.Sprintf("%s (category: %s)", a.scientificName, a.AnimalCategory)
	return 1
}

func (ac AnimalCategory) String() string {
	return fmt.Sprintf("%s%s%s%s%s%s%s",
		ac.kingdom, ac.phylum, ac.class, ac.order,
		ac.family, ac.genus, ac.species)
}

func main() {
	//category := AnimalCategory{species: "cat",genus: "big cat"}
	//fmt.Printf("The animal category: %s\n",category)
	animal := Animal{
		scientificName: "ccat",
		species:        "new cat",
		AnimalCategory: AnimalCategory{species: "cat", kingdom: "animal"},
	}
	fmt.Printf("The animal : %s\n", animal)
	fmt.Printf("The animal : %v\n", animal.String())
}

输出

The animal : {ccat new cat animalcat}
The animal : 1

String()方法的说明

package main

import "fmt"

// AnimalCategory 代表动物分类学中的基本分类法。
type AnimalCategory struct {
	kingdom string // 界。
	phylum  string // 门。
	class   string // 纲。
	order   string // 目。
	family  string // 科。
	genus   string // 属。
	species string // 种。
}

type Animal struct {
	scientificName string
	species        string
	AnimalCategory
}

func (a Animal) Category() string {
	return a.AnimalCategory.String()
}

func (a Animal) String() int {
	//fmt.Println(a)
	//return fmt.Sprintf("%s (category: %s)", a.scientificName, a.AnimalCategory)
	return 1
}

func (ac AnimalCategory) String() string {
	return fmt.Sprintf("%s%s%s%s%s%s%s",
		ac.kingdom, ac.phylum, ac.class, ac.order,
		ac.family, ac.genus, ac.species)
}

func main() {
	//category := AnimalCategory{species: "cat",genus: "big cat"}
	//fmt.Printf("The animal category: %s\n",category)
	animal := Animal{
		scientificName: "ccat",
		species:        "new cat",
		AnimalCategory: AnimalCategory{species: "cat", kingdom: "animal"},
	}
	//fmt.Printf("The animal : %s\n", animal)
	//fmt.Printf("The animal : %v\n", animal.String())
	fmt.Println(animal)
	fmt.Println(animal.String())
}