1.继承
父类:
type Human struct {
name string
sex
string
}
子类: SuperMan子类继承Human父类,将Human写在SuperMan结构体中即可继承
type SuperMan struct {
Human//SuperMan类继承了Human类的方法
level
int
}
重定义父类的方法Eat() 使用子类的*SuperMan
func (this *SuperMan) Eat() {
fmt.Println("SuperMan.Eat()...")
}
子类的新方法
func (this *SuperMan) Fly(){
fmt.Println("SuperMan.Fly()...")
}
定义一个子类对象
s :=SuperMan{Human{"li4","female"},88}
2.多态
接口,本质是一个指针
type AnimalIF interface {
Sleep()
GetColor() string //获取动物的颜色
GetType() string//获取动物的种类
具体的类
type Cat struct {
color string //猫的颜色
}
func (this *Cat) Sleep(){ fmt.Println("Cat is Sleep") }
func(this *Cat) GetColor() string { return this.color }
func(this *Cat) GetType() string{ return "Cat" }
创建对象
var animal AnimalIF//接口的数据类型,父类指针 animal=&Cat{"Green"}
animal.Sleep()//调用的就是Cat的Sleep()方法,多态的现象
3.空接口和类型断言
Interface{}是万能数据类型
Interface{}用作形参:
func myFunc(arg interface{}) {
fmt.Println("myFunc is called...")
fmt.Println(arg)
}
4.pair结构
5.反射
在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。
反射机制就是在运行时动态的调用对象的方法和属性
- 变量包括(type, value)两部分
- type 包括 static type和concrete type. 简单来说 static type是你在编码是看见的类型(如int、string),concrete type是runtime系统看见的类型
- 类型断言能否成功,取决于变量的concrete type,而不是static type. 因此,一个 reader变量如果它的concrete type也实现了write方法的话,它也可以被类型断言为writer.
只有interface类型才有反射一说。
reflect.Value是通过reflect.ValueOf(X)获得的,只有当X是指针的时候,才可以通过reflec.Value修改实际变量X的值,即:要修改反射类型的对象就一定要保证其值是“addressable”的。
- newValue.CantSet()表示是否可以重新设置其值,如果输出的是true则可修改,否则不能修改,修改完之后再进行打印发现真的已经修改了。
package main
import (
"fmt"
"reflect"
)
type User struct {
Id int
Name string
Age int
}
func (u User) ReflectCallFuncHasArgs(name string, age int) {
fmt.Println("ReflectCallFuncHasArgs name: ", name, ", age:", age, "and origal User.Name:", u.Name)
}
func (u User) ReflectCallFuncNoArgs() {
fmt.Println("ReflectCallFuncNoArgs")
}
如何通过反射来进行方法的调用?
本来可以用u.ReflectCallFuncXXX直接调用的,但是如果要通过反射,那么首先要将方法注册,也就是MethodByName,然后通过反射调动mv.Call
func main() {
user := User{1, "Allen.Wu", 25}
- 要通过反射来调用起对应的方法,必须要先通过reflect.ValueOf(interface)来获取到reflect.Value,得到“反射类型对象”后才能做下一步处理
getValue := reflect.ValueOf(user)
一定要指定参数为正确的方法名
- 先看看带有参数的调用方法
methodValue := getValue.MethodByName("ReflectCallFuncHasArgs")
args := \[]reflect.Value{reflect.ValueOf("wudebao"), reflect.ValueOf(30)}
methodValue.Call(args)
一定要指定参数为正确的方法名
- 再看看无参数的调用方法
methodValue = getValue.MethodByName("ReflectCallFuncNoArgs")
args = make(\[]reflect.Value, 0)
methodValue.Call(args)
运行结果:
ReflectCallFuncHasArgs name: wudebao , age: 30 and origal User.Name: Allen.Wu
ReflectCallFuncNoArgs
Golang的反射很慢