Go语言16-高级-面向对象——继承

面向对象——继承

1.嵌套结构体

结构体内的字段有可能也是一个结构体,这样的结构体称为嵌套结构体。

package main

import "fmt"

type Animal struct {
	name  string
	age   int
	color string
}
type dog struct {
	animal  Animal
	address string
}

func main() {
	d := dog{Animal{"wangcai", 10, "white"}, "上海"}
	fmt.Printf("d=%+v\n", d)
	/*访问嵌入式结构体内部成员,需要显式调用*/
	fmt.Printf("name=%s,age=%d,color=%s,address=%s\n", d.animal.name, d.animal.age, d.animal.color, d.address)
	var t dog
	t.animal.name = "旺财"
	t.animal.age = 5
	t.animal.color = "白色"
	t.address = "北京"
	fmt.Printf("t=%+v\n", t)
}

2.匿名组合

如果结构体中的匿名字段是结构体,那么这个结构体所拥有的全部字段都被隐式的引入了当前定义的这个结构体。这种结构体内部嵌套匿名结构体的组合称作匿名组合。而匿名结构体中的成员可以通过外部结构体直接访问。

package main

import "fmt"

type Animal struct {
	name  string
	age   int
	color string
}
type dog struct {
	/*匿名字段,默认dog包含了Animal中的所有字段*/
	Animal
	address string
}

func main() {
	//顺序初始化,成员赋值要一一对应
	d1 := dog{Animal{"wangcai", 10, "white"}, "上海"}
	fmt.Printf("d1=%+v\n", d1)
	fmt.Printf("name=%s,age=%d,color=%s,address=%s\n", d1.name, d1.age, d1.color, d1.address)
	//部分初始化
	d2 := dog{Animal: Animal{name: "xiaoqiang", color: "blue"}}
	fmt.Printf("d2=%+v\n", d2)
	var d3 dog
	/*匿名字段内部成员直接调用*/
	d3.name = "旺财" //等价于d3.Animal.name="旺财"
	d3.age = 5
	d3.color = "白色"
	d3.address = "北京"
	fmt.Printf("d3=%+v\n", d3)
}

3.同名字段

外部结构体的成员变量名和嵌入的内部结构体成员变量名相同,则此外部结构体成员被称作同名字段。同名字段,可以通过外部结构体直接访问,但是内部结构体成员变量的访问需要显示调用。

package main

import "fmt"

type Animal struct {
	name  string
	age   int
	color string
}
type dog struct {
	Animal  //匿名字段
	address string
	name    string //同名字段
}

func main() {
	var d dog
	d.name = "旺财" //默认给最外层的 成员赋值
	fmt.Printf("d=%+v\n", d)
	//给匿名字段内的同名字段赋值,需要显示调用
	d.Animal.name = "wangcai"
	d.age = 5
	d.color = "白色"
	d.address = "北京"
	fmt.Printf("d=%+v\n", d)
}

4.其他匿名字段

匿名字段不仅可以是结构体类型,还可以是其他任意的内置类型和自定义类型,甚至可以是结构体的指针类型。

4.1 非结构体类型

非结构体类型包括:所有的内置类型和自定义类型。

4.2 结构体指针类型

匿名字段逼近可以是结构体类型,也可以是结构体指针类型

  • 非结构体类型
package main

import "fmt"

type Animal struct {
	name  string
	age   int
	color string
}
type mystr string // 自定义类型
type dog struct {
	Animal //匿名字段,结构体类型
	string //匿名字段,内置类型
	mystr  //匿名字段,自定义类型
}

func main() {
	d := dog{Animal{"wangcai", 1, "white"}, "上海", "二哈"}
	d.mystr = "旺财"
	fmt.Printf("d=%+v\n", d)
	fmt.Printf("Animal.name=%s,Animal.age=%d,Animal.color=%s,address=%s,name=%s\n", d.name, d.age, d.color, d.string, d.mystr)
}
  • 结构体指针类型
package main

import "fmt"

type Animal struct {
	name  string
	age   int
	color string
}
type dog struct {
	*Animal //匿名字段,结构体指针类型
	address string
}

func main() {
	d := dog{&Animal{"wangcai", 1, "white"}, "上海"}
	fmt.Printf("d=%+v\n", d)
	fmt.Printf("name=%s,age=%d,color=%s,address=%s\n",
		d.name, d.age, d.color, d.address)
	var t dog
	t.Animal = new(Animal) //分配内存空间
	t.name = "旺财"
	t.age = 2
	t.color = "白色"
	t.address = "北京"
	fmt.Printf("t=%+v\n", t)
	fmt.Printf("name=%s,age=%d,color=%s,address=%s\n", t.name, t.age, t.color, t.address)
}

5.方法的继承与重写

5.1 方法的继承

如果嵌套结构体的内部结构体实现了一个方法,但是外部结构体没有实现这个方法。
如果匿名组合的匿名字段实现了一个方法,那么外部结构体也就实现了这个方法。

5.2 方法的重写

匿名组合的匿名字段实现了一个方法。如果外部结构体对此方法进行了修改,这就叫做方法的重写。

  • 方法的继承
package main

import "fmt"

type Animal struct {
	name  string
	age   int
	color string
}
type dog struct {
	//匿名字段,默认dog包含了Animal中的所有字段
	Animal
	address string
}

func (a *Animal) eat() {
	fmt.Println("It likes eat.")
}
func (d *dog) sing() {
	fmt.Println("It's singing.")
}
func main() {
	d1 := dog{Animal{"wangcai", 10, "white"}, "上海"}
	fmt.Printf("d1=%+v\n", d1)
	d1.eat()
	//继承了方法eat
	d1.sing()
}
  • 方法的重写
package main

import "fmt"

type Animal struct {
	name  string
	age   int
	color string
}
type dog struct {
	//匿名字段,默认dog包含了Animal中的所有字段
	Animal
	address string
}

func (a *Animal) eat() {
	fmt.Println("It likes eat.")
}
func (d *dog) eat() {
	fmt.Println("dog like eat.")
}
func main() {
	d1 := dog{Animal{"wangcai", 10, "white"}, "上海"}
	fmt.Printf("d1=%+v\n", d1)
	d1.eat()
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值