go语言interface接口继承多态怎么定义

本篇内容介绍了“go语言interface接口继承多态怎么定义”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

    1.什么是接口

    接口就是一种规范与标准,在生活中经常见接口,例如:笔记本电脑的USB接口,可以将任何厂商生产的鼠标与键盘,与电脑进行链接。为什么呢?原因就是,USB接口将规范和标准制定好后,各个生产厂商可以按照该标准生产鼠标和键盘就可以了。

    在程序开发中,接口只是规定了要做哪些事情,干什么。具体怎么做,接口是不管的。这和生活中接口的案例也很相似,例如:USB接口,只是规定了标准,但是不关心具体鼠标与键盘是怎样按照标准生产的.

    在企业开发中,如果一个项目比较庞大,那么就需要一个能理清所有业务的架构师来定义一些主要的接口,这些接口告诉开发人员你需要实现那些功能。

    2.接口定义

    接口定义的语法如下:

    方式一:interface接收任意数据格式
    //先定义接口  一般以er结尾  根据接口实现功能
    type CurrencyEr2 interface{
    	Symbol() string
    }
    
    方式二:指定类型
    type Currency string

    怎样具体实现接口中定义的方法呢?

    func (c Currency)Symbol() string {
    	m := ""
    	switch c {
    	case "CNY":
    		// 人民币
    		m = "¥"
    	case "KRW":
    		// 韩币
    		m = "₩"
    	case "TWD":
    		// 台币
    		m = "$"
    	case "JPY":
    		// 日元
    		m = "¥"
    	case "USD":
    		// 美元
    		m = "$"
    	}
    	return m
    }

    具体的调用如下:

    func main() {
      // 方式一:
      a:=CurrencyEr2(Currency("CNY")).Symbol()
    	fmt.Println(a)
      // 方式二:
    	b:=Currency("CNY").Symbol()
    	fmt.Println(b)
    }

    只要类(结构体)实现对应的接口,那么根据该类创建的对象,可以赋值给对应的接口类型。

    接口的命名习惯以er结尾。

    3.多态

    接口有什么好处呢?实现多态。

    多态就是同一个接口,使用不同的实例而执行不同操作

    所谓多态指的是多种表现形式,如下图所示:

    使用接口实现多态的方式如下:

    package main
    import "fmt"
    //先定义接口  一般以er结尾  根据接口实现功能
    type CurrencyEr2 interface {
    	//方法  方法的声明
    	Symbol() string
    }
    type Currency string
    type Currency2 string
    func (c Currency) Symbol() string {
    	m := ""
    	switch c {
    	case "CNY":
    		m = "¥"
    	}
    	return m
    }
    func (c Currency2) Symbol() string {
    	m := ""
    	switch c {
    	case "USD":
    		m = "$"
    	}
    	return m
    }
    //多态的实现
    //将接口作为函数参数  实现多态
    func Start(c CurrencyEr2) string {
    	return c.Symbol()
    }
    func main() {
    	//调用多态函数
    	a := Start(Currency("CNY"))
    	fmt.Println(a)
    	//调用多态函数
    	b := Start(Currency2("USD"))
    	fmt.Println(b)
    }

    多态加减计算器

    package main
    import "fmt"
    //定义接口
    type Opter interface {
    	//方法声明
    	Result() int
    }
    //父类结构体
    type Operate struct {
    	num1 int
    	num2 int
    }
    //加法子类结构体
    type Add struct {
    	Operate
    }
    //实现加法子类的方法
    func (a *Add) Result() int {
    	return a.num1 + a.num2
    }
    //减法子类结构体
    type Sub struct {
    	Operate
    }
    //实现减法子类的方法
    func (s *Sub) Result() int {
    	return s.num1 - s.num2
    }
    //创建一个类负责对象创建
    //工厂类
    type Factory struct {
    }
    func (f *Factory) Result(num1 int, num2 int, ch string) int {
    	sum := 0
    	switch ch {
    	case "+":
    		var a Add
    		a.num1 = num1
    		a.num2 = num2
    		sum = Opter.Result(&a)
    	case "-":
    		var s Sub
    		s.num1 = num1
    		s.num2 = num2
    		sum = Opter.Result(&s)
    	}
    	return sum
    }
    //通过设计模式调用
    func main() {
    	//创建工厂对象
    	var f Factory
    	a:= f.Result(10, 20, "+")
    	fmt.Println(a)
    }

    4.接口继承与转换

    接口也可以实现继承:

    package main
    import "fmt"
    //先定义接口  一般以er结尾  根据接口实现功能
    type Humaner2 interface {   //子集
        //方法  方法的声明
        sayhi()
    }
    type Personer interface {  //超集
        Humaner2   //继承sayhi()
    
        sing(string)
    }
    type student13 struct {
        name  string
        age   int
        score int
    }
    func (s *student13)sayhi()  {
        fmt.Printf("大家好,我是%s,今年%d岁,我的成绩%d分\n",s.name,s.age,s.score)
    }
    func (s *student13)sing(name string)  {
        fmt.Println("我为大家唱首歌",name)
    }
    func main() {
        //接口类型变量定义
        var h Humaner2
        var stu student13 = student13{"小吴",18,59}
        h = &stu
        h.sayhi()
        //接口类型变量定义
        var p Personer
        p = &stu
        p.sayhi()
        p.sing("大碗面")
    }

    接口继承后,可以实现“超集”接口转换“子集”接口,代码如下:

    package main
    import "fmt"
    //先定义接口  一般以er结尾  根据接口实现功能
    type Humaner2 interface {   //子集
        //方法  方法的声明
        sayhi()
    }
    type Personer interface {  //超集
        Humaner2   //继承sayhi()
        sing(string)
    }
    type student13 struct {
        name  string
        age   int
        score int
    }
    func (s *student13)sayhi()  {
        fmt.Printf("大家好,我是%s,今年%d岁,我的成绩%d分\n",s.name,s.age,s.score)
    }
    func (s *student13)sing(name string)  {
        fmt.Println("我为大家唱首歌",name)
    }
    func main()  {
        //接口类型变量定义
        var h Humaner2  //子集
        var p Personer    //超集
        var stu student13 = student13{"小吴",18,59}
        p = &stu
        //将一个接口赋值给另一个接口
        //超集中包含所有子集的方法
        h = p  //ok
        h.sayhi()
        //子集不包含超集
        //不能将子集赋值给超集
        //p = h  //err
        //p.sayhi()
        //p.sing("大碗面")
    }

    5.空接口

    空接口(interface{})不包含任何的方法,正因为如此,所有的类型都实现了空接口,因此空接口可以存储任意类型的数值。

    例如:

    var i interface{}
    //接口类型可以接收任意类型的数据
    //fmt.Println(i)
    fmt.Printf("%T\n",i)
    i = 10
    fmt.Println(i)
    fmt.Printf("%T\n",i)

    当函数可以接受任意的对象实例时,我们会将其声明为interface{},最典型的例子是标准库fmt中PrintXXX系列的函数,例如:

    func Printf(fmt string, args ...interface{})
    func Println(args ...interface{})

    如果自己定义函数,可以如下:

    func Test(arg ...interface{}) {
    }

    Test( )函数可以接收任意个数,任意类型的参数。

    6.接口转换

    结论:超集可以转换为子集,子集不可以转换为超集

    package main
    import "fmt"
    type Humaner interface { //子集
    	sayhi()
    }
    type Personer interface { //超集
    	Humaner //匿名字段,继承了sayhi()
    	sing(lrc string)
    }
    type Student struct {
    	name string
    	id   int
    }
    //Student实现了sayhi()
    func (tmp *Student) sayhi() {
    	fmt.Printf("Student[%s, %d] sayhi\n", tmp.name, tmp.id)
    }
    func (tmp *Student) sing(lrc string) {
    	fmt.Println("Student在唱着:", lrc)
    }
    func main() {
    	//超集可以转换为子集,反过来不可以
    	var iPro Personer //超集
    	iPro = &Student{"mike", 666}
    	var i Humaner //子集
    	//iPro = i //err
    	i = iPro //可以,超集可以转换为子集
    	i.sayhi()
    }

    7.实现map字典接口

    package main
    import (
    	"fmt"
    	"sync"
    )
    type UserAges struct {
    	ages map[string] int
    	sync.Mutex
    }
    func (u *UserAges)Add(name string,age int)  {
    	u.Lock()
    	defer u.Unlock()
    	u.ages[name] = age
    }
    func (u *UserAges)Get(name string)int{
    	if age,ok:=u.ages[name];ok{
    		return age
    	}
    	return -1
    }
    func main() {
    	dic:=make(map[string]int)
    	dic["age"] = 18
    	r:=UserAges{ages: dic}
    	r.Add("jeff",20)
    	fmt.Println(r)
    	age:=r.Get("age")
    	fmt.Println(age)
    }

    8.interface案例

    package main
    import "fmt"
    type Bike interface {
    	save()
    	update()
    	insert()
    }
    type User struct {
    	name string
    }
    func (this *User) save() {
    	fmt.Println("保存成功", this.name)
    }
    func (this *User) update() {
    	fmt.Println("更新成功", this.name)
    }
    func (this *User) insert() {
    	fmt.Println("插入成功", this.name)
    }
    func main() {
    	var data Bike = &User{name: "jeff"}
    	data.save()
    	data.update()
    	data.insert()
    }

    “go语言interface接口继承多态怎么定义”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注蜗牛博客网站,小编将为大家输出更多高质量的实用文章!

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:niceseo99@gmail.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    评论

    有免费节点资源,我们会通知你!加入纸飞机订阅群

    ×
    天气预报查看日历分享网页手机扫码留言评论Telegram