微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

GO语言interface篇

1.1 interface简洁
interface(接口)是golang最重要的特性之一,Interface类型可以定义一组方法,但是这些不需要实
现。并且interface不能包含任何变量。
◼ interface 是方法的集合
◼ interface是一种类型,并且是指针类型
◼ interface的 更重要的作用在于多态实现
◼ interface 不能包含任何变量

1.2 interface定义

type 接口名称 interface {
	method1 (参数列表) 返回值列表
	method2 (参数列表) 返回值列表
	...
}

1.3 interface使用

◼ 接口的使用不仅仅针对结构体,自定义类型、变量等等都可以实现接口。
◼ 如果一个接口没有任何方法,我们称为空接口,由于空接口没有方法,任意结构体都
隐式地实现了空接口。
◼ 要实现一个接口,必须实现该接口里面的所有方法

//定义接口
type Skills interface {
	Running()
	Getname() string
}
type Student struct {
	Name string
	Age int
}
// 实现接口
func (p Student) Getname() string { //实现Getname方法
	fmt.Println(p.Name)
	return p.Name
}
func (p Student) Running() { // 实现 Running方法
	fmt.Printf("%s running", p.Name)
}
// 使用接口
func main() {
	var skill Skills
	var stu1 Student
	stu1.Name = "darren"
	stu1.Age = 34
	skill = stu1
	skill.Running() //调用接口
}

1.4 interface多态

◼ go语言中interface是实现多态的一种形式,所谓多态,就是一种事物的多种形态
◼ 同一个interface,不同的类型实现,都可以进行调用,它们都按照统一接口进行操作

example:

// 2.4 interface多态

package main

import "fmt"

type Skills interface {
	Running()
	Getname() string
}

type Student struct {
	Name string
	Age  int
}

type Teacher struct {
	Name   string
	Salary int
}

func (p Student) Getname() string { //实现Getname方法
	fmt.Println(p.Name)
	return p.Name
}

func (p Student) Running() { // 实现 Running方法
	fmt.Printf("%s running", p.Name)
}

func (p Teacher) Getname() string { //实现Getname方法
	fmt.Println(p.Name)
	return p.Name
}

func (p Teacher) Running() { // 实现 Running方法
	fmt.Printf("\n%s running", p.Name)
}
func main() {
	var skill Skills
	var stu1 Student
	var t1 Teacher
	t1.Name = "king"
	stu1.Name = "darren"
	stu1.Age = 22
	skill = stu1
	skill.Running()
	skill = t1
	skill.Running()
}

执行结果:
darren running
king running

1.5 interface接口嵌套

◼ go语言中的接口可以嵌套,可以理解为继承,子接口拥有父接口的所有方法
◼ 如果使用该子接口,必须将父接口和子接口的所有方法都实现
example:

// 2.5 interface接口嵌套
package main

import "fmt"
type Skills interface {
	Running()
	// Running(is int)		// 函数名是唯一的
	Getname() string
}

type Test interface {
	Sleeping()
	Skills //继承Skills
}
type Student struct {
	Name string
	Age  int
}

type Teacher struct {
	skill  Skills // skill也只能当变量去用
	Name   string
	Salary int
}

func (p Student) Getname() string { //实现Getname方法
	fmt.Println(p.Name)
	return p.Name
}

func (p Student) Running() { // 实现 Running方法
	fmt.Printf("%s running", p.Name)
}

func (p Teacher) Getname() string { //实现Getname方法
	fmt.Println(p.Name)
	return p.Name
}

func (p Teacher) Running() { // 实现 Running方法
	fmt.Printf("\n%s running", p.Name)
}

func (p Teacher) Sleeping() { // 实现 Sleeping方法
	fmt.Printf("\n%s Sleeping", p.Name)
}
func main() {
	var skill Skills
	var stu1 Student
	var t1 Teacher
	t1.Name = "king"
	stu1.Name = "darren"
	stu1.Age = 22
	skill = stu1
	skill.Running()
	skill = t1
	skill.Running()
	
	var test Test
	test = t1
	test.Sleeping()
	test.Running()
}

执行结果:
darren running
king running
king Sleeping
king running

1.6 interface接口组合

◼ 接口的定义也支持组合继承

// 2.6 接口的组合继承
package main

import "fmt"

// 可以闻
type Smellable interface {
	smell()
}
// 可以吃
type Eatable interface {
	eat()
}
type Fruitable interface {
	Smellable
	Eatable
}
// 苹果既可能闻又能吃
type Apple struct{}

func (a Apple) smell() {
	fmt.Println("apple can smell")
}

func (a Apple) eat() {
	fmt.Println("apple can eat")
}

// 花只可以闻
type Flower struct{}

func (f Flower) smell() {
	fmt.Println("flower can smell")
}

func main() {
	var s1 Smellable
	var s2 Eatable
	var apple = Apple{}
	var flower = Flower{}
	s1 = apple
	s1.smell()
	s1 = flower
	s1.smell()
	s2 = apple
	s2.eat()

	fmt.Println("\n组合继承")
	var s3 Fruitable
	s3 = apple
	s3.smell()
	s3.eat()
}

1.7 interface类型转换

由于接口是一般类型,当我们使用接口时候可能不知道它是那个类型实现的,
基本数据类型我们有对应的方法进行类型转换,当然接口类型也有类型转换。

var s int
var x interface
x = s
y , ok := x.(int)
//将interface 转为int,ok可省略 但是省略以后转换失败会报错,
true转换成功,false转换失败, 并采用认值

1.8 interface类型判断

package main

import "fmt"

type Student struct {
	Name string
}

func TestType(items ...interface{}) {
	for k, v := range items {
		switch v.(type) {
		case string:
			fmt.Printf("type is string, %d[%v]\n", k, v)
		case bool:
			fmt.Printf("type is bool, %d[%v]\n", k, v)
		case int:
			fmt.Printf("type is int, %d[%v]\n", k, v)
		case float32, float64:
			fmt.Printf("type is float, %d[%v]\n", k, v)
		case Student:
			fmt.Printf("type is Student, %d[%v]\n", k, v)
		case *Student:
			fmt.Printf("type is Student, %d[%p]\n", k, v)
		}
	}
}

func main() {
	var stu Student
	TestType("darren", 100, stu, 3.3, &stu, true)
}

执行结果:
type is string, 0[darren]
type is int, 1[100]
type is Student, 2[{}]
type is float, 3[3.3]
type is Student, 4[0xc000040240]
type is bool, 5[true]

1.9 指向指针的接口变量

package main

import "fmt"

type Rect struct {
	Width  int
	Height int
}

func main() {
	var a interface{}
	var r = Rect{50, 50}
	a = &r // 指向了结构体指针

	var rx = a.(*Rect) // 转换成指针类型
	r.Width = 100
	r.Height = 100
	fmt.Println("r:", r)
	fmt.Println("rx:", rx)
	fmt.Printf("rx:%p, r:%p\n", rx, &r)
}

执行结果:
r: {100 100}
rx: &{100 100}
rx:0xc0000160c0, r:0xc0000160c0

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐