go interface接口

interface接口

定义:Interface类型可以定义一组方法,但是这些不需要实现。并且interface不能 包含任何变量。

type example interface{
        Method1(参数列表) 返回值列表
        Method2(参数列表) 返回值列表
        …
}

interface类型默认是一个指针

样例一:

package main

import "fmt"

type People struct {
	name string
	age  int
}

type Test interface {
	Print()
	Sleep()
}

type Student struct {
	name  string
	age   int
	score int
}

func (p Student) Print() {
	fmt.Println("name:", p.name)
	fmt.Println("age:", p.age)
	fmt.Println("score:", p.score)
}

func (p Student) Sleep() {
	fmt.Println("student sleep")
}

func (people People) Print() {
	fmt.Println("name:", people.name)
	fmt.Println("age:", people.age)
}

func (p People) Sleep() {
	fmt.Println("people sleep")
}

func main() {

	var t Test
	fmt.Println(t)
	//t.Print()

	var stu Student = Student{
		name:  "stu1",
		age:   20,
		score: 200,
	}

	t = stu
	t.Print()
	t.Sleep()

	var people People = People{
		name: "people",
		age:  100,
	}

	t = people
	t.Print()
	t.Sleep()

	fmt.Println("t:", t)
}

 

样例二:

package main

import "fmt"

type Carer interface {
	GetName() string
	Run()
	DiDi()
}

type Test interface {
	Hello()
}

type BMW struct {
	Name string
}

func (p *BMW) GetName() string {
	return p.Name
}

func (p *BMW) Run() {
	fmt.Printf("%s is running\n", p.Name)
}

func (p *BMW) DiDi() {
	fmt.Printf("%s is didi\n", p.Name)
}

func (p *BMW) Hello() {
	fmt.Printf("hello, i'm %s \n", p.Name)
}

type BYD struct {
	Name string
}

func (p *BYD) GetName() string {
	return p.Name
}

func (p *BYD) Run() {
	fmt.Printf("%s is running\n", p.Name)
}

func (p *BYD) DiDi() {
	fmt.Printf("%s is didi\n", p.Name)
}

func main() {
	var car Carer
	var test Test

	fmt.Println(car)

	bmw := &BMW{
		Name: "BMW",
	}

	car = bmw
	car.Run()

	test = bmw
	test.Hello()

	byd := &BYD{
		Name: "BYD",
	}

	car = byd
	car.Run()
}

 

接口实现

Golang中的接口,不需要显示的实现。只要一个变量,含有接口类型中 的所有方法,那么这个变量就实现这个接口。因此,golang中没有implement 类似的关键字。

如果一个变量含有了多个interface类型的方法,那么这个变量就实现了多个 接口。

如果一个变量只含有了1个interface的方部分方法,那么这个变量没有实现 这个接口。

 

多态

一种事物的多种形态,都可以按照统一的接口进行操作

 

接口嵌套

一个接口

可以嵌套在另外的接口

type ReadWrite interface {
               Read(b Buffer) bool
               Write(b Buffer) bool
} 

type Lock interface {
               Lock()
               Unlock() 
} 

type File interface {
               ReadWrite
               Lock 
               Close() 
} 

样例一:

package main

import "fmt"

type Reader interface {
	Read()
}

type Writer interface {
	Write()
}

type ReadWriter interface {
	Reader
	Writer
}

type File struct {
}

func (f *File) Read() {
	fmt.Println("read data")
}

func (f *File) Write() {
	fmt.Println("write data")
}

func Test(rw ReadWriter) {
	rw.Read()
	rw.Write()
}

func main() {
	var f File
	Test(&f)
}

判断一个变量是否实现了指定接口

package main

import "fmt"

type Reader interface {
	Read()
}

type Writer interface {
	Write()
}

type ReadWriter interface {
	Reader
	Writer
}

type File struct {
}

func (f *File) Read() {
	fmt.Println("read data")
}

func (f *File) Write() {
	fmt.Println("write data")
}

func main() {
	var f *File
	var b interface{}
	b = f
	v, ok := b.(ReadWriter)
	fmt.Println(v, ok)
}

 

类型断言

由于接口是一般类型,不知道具体类型,如果要转成具体类型,可以采用以下方法进行转换:

var t int
var x interface{}
x = t
y = x.(int)   //转成int
或者
var t int
var x interface{}
x = t
y, ok = x.(int)   //转成int,带检查

样例:

package main

import "fmt"

type Student struct {
	Name string
	Sex  string
}

func Test(a interface{}) {
	b, ok := a.(Student)
	if ok == false {
		fmt.Println("convert failed")
		return
	}
	//b += 3
	fmt.Println(b)
}

func just(items ...interface{}) {
	for index, v := range items {
		switch v.(type) {
		case bool:
			fmt.Printf("%d params is bool, value is %v\n", index, v)
		case int, int64, int32:
			fmt.Printf("%d params is int, value is %v\n", index, v)
		case float32, float64:
			fmt.Printf("%d params is float, value is %v\n", index, v)
		case string:
			fmt.Printf("%d params is string, value is %v\n", index, v)
		case Student:
			fmt.Printf("%d params student, value is %v\n", index, v)
		case *Student:
			fmt.Printf("%d params *student, value is %v\n", index, v)
		}
	}
}

func main() {
	var b Student = Student{
		Name: "stu01",
		Sex:  "female",
	}
	Test(b)
	just(28, 8.2, "this is a test", b, &b)
}

 

空接口

空接口没有任何方法,所以所有类型都实现了空接口,也就是任何变量都可以赋值给空接口。

var a int
var b interface{}
b  = a

备注:变量slice和接口slice之间赋值操作,for range

 

通用的链表类

link.go

package main

import "fmt"

type LinkNode struct {
	data interface{}
	next *LinkNode
}

type Link struct {
	head *LinkNode
	tail *LinkNode
}

func (p *Link) InsertHead(data interface{}) {
	node := &LinkNode{
		data: data,
		next: nil,
	}

	if p.tail == nil && p.head == nil {
		p.tail = node
		p.head = node
		return
	}

	node.next = p.head
	p.head = node
}

func (p *Link) InsertTail(data interface{}) {
	node := &LinkNode{
		data: data,
		next: nil,
	}

	if p.tail == nil && p.head == nil {
		p.tail = node
		p.head = node
		return
	}

	p.tail.next = node
	p.tail = node
}

func (p *Link) Trans() {
	q := p.head
	for q != nil {
		fmt.Println(q.data)
		q = q.next
	}
}

main.go

package main

import "fmt"

func main() {

	var link Link
	for i := 0; i < 10; i++ {
		//intLink.InsertHead(i)
		link.InsertTail(fmt.Sprintf("str %d", i))
	}

	link.Trans()
}

 

posted @ 2017-08-30 16:20  shhnwangjian  阅读(310)  评论(0编辑  收藏  举报