【Go语言】2.6面向对象之interface

//面向对象之interface
package main

import (
	. "fmt"
	"reflect"
)

//明确概念:interface 就是一组method的组合,通过interface来定义对象的一组行为
//interface类型定义了一组方法,如果某个对象实现了某个接口的所有方法,则此对象就实现了此接口

type Human interface {
	say(msg string)
}
type People interface {
	worker(info string)
}

type Man struct { //Man对象实现了Human、People两个接口
	name string
}

func (m Man) say(msg string) {
	Println("他的名字是:", m.name, " 他说:", msg)
}

func (m Man) worker(info string) {
	Println("他的工作是:", info)
}

type Student struct { //Student对象继承了Man对象并且覆盖了父类中一个接口实现的方法
	Man
	nick string
}

func (s Student) worker() {
	Println("学生没有工作")
}

func testInterface() {
	man := Man{"摩西"}
	man.say("大家好")
	man.worker("码农")

	stu := Student{Man{"chris"}, "摩西,摩西"}
	stu.say("好好学习")
	stu.Man.worker("学习")
	stu.worker()

}

///测试空interface{}
func emptyInterface() {
	/*
			空interface
		如果一个函数的参数是interface{} , 那么它可以接受任何类型的值作为参数
		如果一个函数的返回值是interface{},那么它可以返回任何类型的值
	*/
	Println("==空interface==")
	var a interface{} //定义a为空接口,a可以储存任何类型的值
	str := "摩西"
	a = str
	Println(a)
	num := 123
	a = num
	Println(a)
}

///interface储存的变量的类型
type Element interface{} //定义为空interface

type List []Element //定义一个slice

func (m Man) String() string { //现了 Stringer, Println的时候可以自定义输出格式
	return "对象:Man{name:" + m.name + "}"
}

func testInterfaceType() {
	list := make(List, 4)
	list[0] = 123
	list[1] = "摩西"
	list[2] = Man{"chris"}
	list[3] = false

	Println("使用Comma-ok 断言(类似 value,istrue := 变量.(类型))判断类型")
	for index, element := range list {
		if value, ok := element.(int); ok {
			Printf("list[%d] is int, value = %d\n", index, value)
		} else if value, ok := element.(string); ok {
			Printf("list[%d] is string, value = %s\n", index, value)
		} else if value, ok := element.(Man); ok { //自定义输出格式 实现了Stringer
			Printf("list[%d] is Man, value = %s\n", index, value) //list[2] is Man, value = 对象:Man{name:chris}
		} else if value, ok := element.(bool); ok {
			Printf("list[%d] is bool, value = %t\n", index, value)
		} else {
			Printf("list[%d] is different type\n", index)
		}
	}

	//使用switch实现上面的输出
	Println("使用switch实现类型判断输出")
	for index, element := range list {
		switch value := element.(type) { //element.(type)语法不能在 switch 外的任何逻辑里面使用
		case int:
			Printf("list[%d] is int, value = %d\n", index, value)
		case string:
			Printf("list[%d] is string, value = %s\n", index, value)
		case Man:
			Printf("list[%d] is Man, value = %s\n", index, value)
		case bool:
			Printf("list[%d] is bool, value = %t\n", index, value)
		default:
			Printf("list[%d] is different type\n", index)
		}
	}
}

///嵌入interface
type Demo interface { //我们说Demo接口嵌入了Human接口,把Human的方法隐含的包含进来了
	Human                           //隐含的包含了Human这个interface
	pushCode(code interface{}) bool //传入任何类型的方法,返回布尔值
	pullCode() (interface{}, bool)  //返回任何类型和布尔值的方法
}

//关于反射
func main() {
	// Println("关于反射")
	// var num float64 = 4.5
	// v := reflect.ValueOf(num)
	// Println(v)
	// Println("type:", v.Type())
	// Println("kind is float64:", v.Kind() == reflect.Float64)
	// Println("value:", v.Float())

	Println("=====对象反射=====")
	// dog := Dog{"小黑", 2}
	for name, mtype := range attributes(&Dog{"小黑", 4}) {
		Printf("Name: %s, Type %s\n", name, mtype.Name())
	}
}

type Dog struct {
	Name string
	Age  int8
	// Query func()
}

func (d Dog) bark(msg string) string {
	return "Dog name:" + d.Name + ",bark:" + msg + "~"
}

func attributes(m interface{}) map[string]reflect.Type {
	ty := reflect.TypeOf(m)
	if ty.Kind() == reflect.Ptr {
		// Println(reflect.Ptr)
		ty = ty.Elem()
	}
	attrs := make(map[string]reflect.Type)
	if ty.Kind() != reflect.Struct {
		Println(reflect.Struct)
		Printf("%v type can't have attributes inspected\n", ty.Kind())
		return attrs
	}

	for i := 0; i < ty.NumField(); i++ {
		p := ty.Field(i)
		if !p.Anonymous {
			attrs[p.Name] = p.Type
		}
	}
	return attrs
}



转载于:https://my.oschina.net/phpwish/blog/219719

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值