go语言之interface类型

                       What is Interface type in Go ?

在Go语言中什么是接口类型?
GoLang website anguage specification  :

An interface type specifies a method set called its interface. 
A variable of interface type can store a value of any type with a method set that is any superset of the interface. Such a type is said to implement the interface. The value of an uninitialized variable of interface type is nil.

go语言并没有面向对象的相关概念,go语言提到的接口和java、c++等语言提到的接口不同,它不会显示的说明实现了接口,没有继承、子类、implements关键词。
go语言通过隐性的方式实现了接口功能,相对比较灵活。

interface是go语言的一大特性,主要有以下几个特点:

  • interface 是方法或行为声明的集合
  • interface接口方式实现比较隐性,任何类型的对象实现interface所包含的全部方法,则表明该类型实现了该接口。
  • interface还可以作为一中通用的类型,其他类型变量可以给interface声明的变量赋值。
  • interface 可以作为一种数据类型,实现了该接口的任何对象都可以给对应的接口类型变量赋值。

 一、java interface的实现

/* 文件名 : Animal.java */
public interface Animal { 
  public void eat();
  public void travel();
}

/*
文件名 : MammalInt.java */ public class MammalInt implements Animal{ public void eat(){ System.out.println("Mammal eats"); } public void travel(){ System.out.println("Mammal travels"); } public int noOfLegs(){ return 0; } public static void main(String args[]){ MammalInt m = new MammalInt(); m.eat(); m.travel(); } }

二、go interface的实现
   go语言提到的接口和java、c++等语言提到的接口不同,它不会显示的说明实现了接口,没有继承、子类、implements关键词

接口实现
package main
import "fmt"
//从语法上看,Interface定义了一个或一组method(s),这些method(s)只有函数签名,没有具体的实现代码
type Animal interface { GetAge() int32 GetType() string } type Dog struct { Age int32 Type string } func (a *Dog) GetAge() int32 { return a.Age } func (a *Dog) GetType() string { return a.Type } func main() { animal := &Dog{Age: 20, Type: "DOG"} fmt.Printf("%s max age is: %d", animal.GetType(), animal.GetAge()) }

 三、接口类型和方法实现

首先说明下接口的实现,最基础的接口构成由interface类型和一或多个方法组成
1.接口的声明
type 接口名 interface {
    方法1(参数) 返回值
    方法2(参数) 返回值
    方法3(参数) 返回值
}
2.方法声明
Go方法就是有特定接收者的函数。Go中的函数由函数名,参数,返回值,函数体构成,方法在函数的基础上多了接收值:

func (接收者,接收者类型) 方法名(接收参数) (返回值){
    函数体
} 
3.实现接口的方法
举个例子,下面定义一个接口叫annimal,里面有个buy的方法

  package main
  import (
    "fmt"
  )

type annimal interface {
    do()
}
//定义一个字符串类型
type str string
//使字符串类型通过buyer接口调用buy方法
//实现了接口do接口,打印
func (m str) do() {
    fmt.Println("it is mine")
}
 
func main() {
    //声明一个annimal接口bird
    var bird annimal
    //实例化str给bird
    bird = str("I'm aozhejin")
    //调用方法
    bird.do()
}

 四、interface作为通用类型

package main
import (
   "fmt"
)
type User struct {
   Id int
   Name string
   Amount float64
}
func main() {
   var i interface{}
   i = "string"
   fmt.Println(i)
   i = 1
   fmt.Println(i)
   i = User{Id: 2}
   //i.(User).Id = 15  //运行此处会报错,在函数中修改interface表示的结构体的成员变量的值,编译时遇到这个编译错误,cannot assign to i.(User).Id
   fmt.Println(i.(User).Id)
   i = &User{Id: 2}
   i.(*User).Id = 15
   fmt.Println(i.(*User).Id)
}

 五、interface与struct之间可以相互转换
   struct不需要像java在源码中显示说明实现了某个接口,可以通过约定的形式,隐式的转换到interface,还可以在运行时查询接口类型,这样有种用动态语言写代码的感觉,但是又可以在编译时进行检查,捕捉一些明显的类型不匹配的错误。

type Strr interface {
    String() string
}
type str string //定义一个字符串类型别名 type Stru
struct { i int } func (s *Stru) String() string { return fmt.Sprintf("%d", s.i) } func Print(s Strr) { println(s.String()) } func DynamicPrint(any interface{}) { if s, ok := any.(Strr); ok { Print(s) } } func main() { var stru Stru s.i = 123456789 Print(&s) DynamicPrint(&s) }

 

posted @ 2022-05-20 15:23  jinzi  阅读(29)  评论(0编辑  收藏  举报