2022/02/07
package main
import "fmt"
/*
1.结构体可以使用嵌套匿名结构体里面的所有字段和方法,
首字符大写或者小写的字段,方法都可以使用
2.匿名结构体字段访问可以简化
b.A.age = 18 // --> b.age = 18//可以简化
会先从b结构体中找age,如果找不到会从嵌入的A结构体中找
3.当结构体和匿名结构体有相同的字段或者方法时,编译器采用就近访问
原则,如果想要使用嵌入的匿名结构体中的变量需要指定嵌入的结构体
4.结构体嵌入两个或多个匿名结构体,如两个匿名结构体有相同的字段和方法,同时,
结构体本身没有同名的字段和方法,在这种情况下,访问时,就必须指定匿名
结构体的名字,否则会编译报错.
如果结构体C中有字段的话,不会报错
5.如果一个struct嵌套了一个有名结构体,这种模式就是组合,如果是组合关系
那么在访问组合的结构体的字段或方法时,必须带上结构体的名字
6.嵌套匿名结构体后,也可以在创建结构体变量时,直接指定各个匿名结构体字段的值
*/
type A struct {
Name string
age int
}
type B struct {
A
Name string
age int
}
type C struct {
A
B
}
//有名结构体
//编译器直接在D中找Name字段,如果找不到就直接报错没有
type D struct {
a A
}
func (a *A) SayOK() {
fmt.Println("A Sayok", a.Name)
}
func (a *A) hello() {
fmt.Println("A Hello", a.Name)
}
func (b *B) hello() {
fmt.Println("A Hello", b.Name)
}
func main() {
var b B
b.Name = "levi"
b.A.Name = "levi haha"
b.age = 18 // --> b.age = 18//可以简化
fmt.Println("b.Name = ", b.Name)
fmt.Println("b.A.Name = ", b.A.Name)
b.SayOK()
b.A.hello()
//4.
var c C
c.A.Name = "mary"
//5.
var d D
d.a.Name = "levi"
//6.
// var b1 B = B{
// A{
// Name: "levi",
// age: 12,
// },
// }
}
package main
import "fmt"
/*
接口不能包含任何变量
1.接口里的所有方法都没有方法体,即接口的方法都是没有实现的方法
接口体现了程序设计的多态和高内聚低耦合的思想
2.golang中的接口,不需要显示的实现,只要一个变量,含有接口类型中的所有方法,
那么这个变量就实现这个接口。
*/
//声明一个接口
type Usb interface {
//声明了两个没有实现的方法
start()
stop()
}
type Phone struct {
}
//让phone实现USB接口的方法
func (p Phone) start() {
fmt.Println("手机开始工作...")
}
func (p Phone) stop() {
fmt.Println("手机停止工作...")
}
type Camaro struct {
}
//让相机实现USB接口的方法
func (c Camaro) start() {
fmt.Println("相机开始工作...")
}
func (c Camaro) stop() {
fmt.Println("相机停止工作...")
}
//计算机
type Computer struct {
}
//编写一个方法Working方法,接收一个usb接口类型变量
//只要是实现了USB接口(就是指实现了Usb接口声明的所有方法)
func (c Computer) Working(usb Usb) {
//通过USB接口变量来调用start和stop方法
usb.start()
usb.stop()
}
func main() {
//测试
var computer Computer = Computer{}
var phone Phone = Phone{}
var camaro Camaro = Camaro{}
//关键点
computer.Working(phone)
computer.Working(camaro)
}
package main
import "fmt"
/*
1.接口本身不能创建实例,但是可以指向一个实现了该接口的自定义类型的变量
2.接口中所有的方法都没有方法体,即都是没有实现的方法
3.在golang中,一个自定义类型需要将某个接口的所有方法都实现,
我们说这个自定义类型实现了该接口
4.一个自定义类型只有实现了某个接口,才能将该自定义类型的实例赋给接口类型
5.只要是自定义数据类型,就可以实现接口,不仅仅是结构体类型
6.一个自定义类型可以实现多个接口
7.一个接口(接口A)可以继承多个别的接口(B,C),
这时如果要实现A接口,也必须将B,C接口的方法也全部实现
//*****继承的B和C接口,不能有相同的方法!!
8.interface类型默认是一个指针(引用类型),(******重要)
如果没有对interface初始化就使用那么会输出nil
9.空接口interface{},没有任何方法,所以所有类型都实现了空接口
即我们可以把任何一个变量赋给空接口类型
*/
type AInterface interface {
Say()
}
type BInterface interface {
AInterface
Talk()
}
//7.如果要实现CInterface接口,
//也必须将AInterface,BInterface接口的方法也全部实现
/*
如果AInterface和BInterface都有一个Test()方法,
相当于CInterface有两个Test()方法,编译器会报错!
*/
type CInterface interface {
AInterface
BInterface
Work()
}
type Persion struct {
}
func (per Persion) Say() {
fmt.Println("Persion say...")
}
func (per Persion) Talk() {
fmt.Println("Persion Talk...")
}
func (per Persion) Work() {
fmt.Println("Persion Work...")
}
type Stu struct {
Name string
}
func (stu Stu) Say() {
fmt.Println("Stu say...")
}
//5.
type integer int
func (i integer) Say() {
fmt.Println("integer say... i = ", i)
}
//9.空接口interface{},没有任何方法,所以所有类型都实现了空接口
type T interface {
}
func main() {
var stu Stu
var a AInterface = stu
a.Say()
var i integer = 10
var b AInterface = i
b.Say()
//7.
var per Persion
var c CInterface = per
c.Say()
c.Talk()
c.Work()
//9
var t T = per // OK的
fmt.Println("t=", t)
var t2 interface{} = per
fmt.Println("t2=", t2)
var num1 float64 = 8.8
t = num1
t2 = num1
fmt.Println("~t=", t)
fmt.Println("~t2=", t2)
}