首页 > 其他分享 >第五篇:接口

第五篇:接口

时间:2023-04-03 20:58:27浏览次数:67  
标签:fmt 接口 第五篇 鸭子 duck Println 唐老鸭

第五篇:接口

目录

一、接口的基本使用

1 接口的介绍

接口:面向对象的领域中,接口一般这样定义,接口定义一个对象的行为,来规范子类对象的行为。

接口是一系列方法的结合【规范行为】。

go和python一样,也是鸭子类型;python中使用abc模块进行约束。go和python虽然推崇鸭子类型,但是在开发过程中,接口还是非常重要的。【有鸭子里面的属性,就叫鸭子,如现在有个鸭子类,内有speak方法 有run方法, 子类只要实现了speak和run,我就认为子类是鸭子】;Java中有接口,子类必须实现鸭子类的所有方法,子类才叫鸭子。

2 定义接口

2.1 接口的简单实用

// 侵入式接口(java 接口没了,子类报错)和非侵入是接口(接口没了,不影响代码,go和python语言中的接口是非侵入式的)

// 1 接口的简单使用
// 定义一个鸭子接口
type Duck interface {
	speak()  // speak方法,这里虽然是函数,但是叫方法
	run()
	//run(name string) (int, int)  // run方法
}

//定义一个普通鸭子结构体
type PDuck struct {
	name string
	sex string
	age int
}

//定义一个唐老鸭结构体
type TDuck struct {
	name string
	sex string
	age int
	wife string
}

// 让普通鸭子和唐老鸭都实现duck接口
// 结构体实现一个接口: 只要绑定接口中的所有方法,就叫实现该接口【只要写完,编辑器就提示已经绑定,太牛了】
func (p PDuck)speak()  {
	fmt.Println("普通鸭子嘎嘎叫,普通鸭子名字叫",p.name)
}

func (p PDuck)run()  {
	fmt.Println("普通鸭子歪歪扭扭走了,普通鸭子名字叫",p.name)
}

//唐老鸭也实现Duck接口
func (p TDuck)speak()  {
	fmt.Println("唐老鸭说人话,唐老鸭子名字叫",p.name)
}
func (p TDuck)run()  {
	fmt.Println("唐老鸭人走路,唐老鸭子名字叫",p.name)
}

2.2 多态的概念【接口实现】

接口的实际使用,接口也是一个类型。其实和Java中的多态一样。【其实这就叫做多态,同一类事物的多种形态】**

【实现接口,只要实现了接口中的所有方法,就会自动进行接口绑定】

// 定义一个鸭子接口
type Duck interface {
	speak()  // speak方法,这里虽然是函数,但是叫方法
	run()
	//run(name string) (int, int)  // run方法
}

//定义一个普通鸭子结构体
type PDuck struct {
	name string
	sex string
	age int
}

//定义一个唐老鸭结构体
type TDuck struct {
	name string
	sex string
	age int
	wife string
}

// 让普通鸭子和唐老鸭都实现duck接口
// 结构体实现一个接口: 只要绑定接口中的所有方法,就叫实现该接口【只要写完,编辑器就提示已经绑定,太牛了】
func (p PDuck)speak()  {
	fmt.Println("普通鸭子嘎嘎叫,普通鸭子名字叫",p.name)
}

func (p PDuck)run()  {
	fmt.Println("普通鸭子歪歪扭扭走了,普通鸭子名字叫",p.name)
}

//唐老鸭也实现Duck接口
func (p TDuck)speak()  {
	fmt.Println("唐老鸭说人话,唐老鸭子名字叫",p.name)
}
func (p TDuck)run()  {
	fmt.Println("唐老鸭人走路,唐老鸭子名字叫",p.name)
}


func main() {
	//// 1 得到一个普通鸭子对象
	//pduck := PDuck{"小黑", "母", 2}
	////2 得到一个堂老鸭子对象
	//tduck:=TDuck{"小唐","男",1,"刘亦菲"}

	var duck Duck  // 生成一个接口对象
	duck = PDuck{"小黑", "母", 2}  // 多态使用
	fmt.Println(duck)  // {小黑 母 2} 此时duck是接口,和平时打印pduck是一样的

	// 接口没有属性,只能.到接口中的两个方法
	duck.speak()  // 普通鸭子嘎嘎叫,普通鸭子名字叫 小黑【执行看左边,接口中存在的方法】
}

2.3 接口内部表示

我们可以把接口看作内部的一个元组 (type, value)。type 是接口底层的具体类型(Concrete Type),而 value 是具体类型的值。

2.4 接口类型转成struct

将接口转化成struct之后,就可以拿到原来的属性和自由方法,不然的话,接口类型只能调用,接口中存在的方法。【Java中进行强制类型转换即可,python中根本没有这个概念,或者说,python压根用不到多态,因为参数中可以传递任何类型的东西】

var duck Duck
duck = PDuck{"小黑", "母", 2}
fmt.Println(duck)  // {小黑 母 2} 此时duck是接口,和平时打印pduck是一样的
// 接口没有属性,只能.到接口中的两个方法
duck.speak()  // 普通鸭子嘎嘎叫,普通鸭子名字叫 小黑【执行看左边,接口中存在的方法】

类型断言:具体模板v, ok := duck.(PDuck),如果断言成功,v为具体类型,ok为true。

// 断言成功
v, ok := duck.(PDuck)  // 将类型进行转换
if ok {
    fmt.Println(v.name)  // 可以对原来的属性进行访问
}

// 断言失败
// v为被断言类型的零值;ok为false

类型选择(通过switch类实现)

// 补充一个奇怪的写法  if后先进行声明,之后ok为true的话。
if v, ok := duck.(PDuck); ok {
    fmt.Println("我是普通鸭子")
	fmt.Println(v.name)
}else if v, ok := duck.(TDuck); ok{
    fmt.Println("我是唐老鸭")
    fmt.Println(v.name)
}


// 使用switch进行替换,即可
func test(duck Duck)  {
    switch duck.(type) {  // type是一个关键字
    case PDuck:
        fmt.Println("我是普通鸭子")
    case TDuck:
        fmt.Println("我是唐老鸭")
    default:
        fmt.Println("我是鸭子这个类")
    }
}


func main() {
	var duck Duck
	duck =  PDuck{"小黑", "母", 2}
	test(duck)  // 我是普通鸭子
	duck = TDuck{"小唐","男",1,"刘亦菲"}
	test(duck)  // 我是唐老鸭
}


// 补充: 断言成功,如何拿到断言的对象
func test(duck Duck)  {
    switch v := duck.(type) {  // v := duck.(type)
    case PDuck:
        fmt.Println(v)  // 此时v为断言成功的对象
        fmt.Println("我是普通鸭子")
    case TDuck:
        fmt.Println("我是唐老鸭")
    default:
        fmt.Println("我是鸭子这个类")
    }
}

// 使用switch进行替换,即可
func test5(b Empty)  {
    switch v:=b.(type) {
    case string:
        fmt.Println("我是字符串")
        fmt.Println(v)
    case int:
        fmt.Println("我是int")
        fmt.Println(v)
    case [3]int:
        fmt.Println("我是数组")
        fmt.Println(v)
    }
}

2.5 空接口

空接口,没有任何方法,所有数据类型都实现了空接口。

// 空接口定义【】
type Empty interface {
	
}

// 空接口使用
var a int = 10
var b string = "yangyi"
var c [3]int
var e Empty
e = a
e = b
e = c

// 空接口的话,我们也可以实现函数传递任何参数,但是使用的话,必须进行断言回来
func test(b Empty)  {
	switch v:=b.(type) {
	case string:
		fmt.Println("我是字符串")
		fmt.Println(v)
	case int:
		fmt.Println("我是int")
		fmt.Println(v)
	case [3]int:
		fmt.Println("我是数组")
		fmt.Println(v)
	}
}

test(e)

2.6 匿名空接口

一般用在形参上。

func test(b interface()){
    
}

// 泛型: 空接口的话,需要进行断言回来; 泛型的话,传什么就是什么,比如说反转函数,反转数字算一个,反转字符串算一个,那还不如写一个统一的泛型。【java和c++中就是如此】
func append(slice []Type, elems ...Type) []Type  

接口是运行时多态,泛型是编译期多态。尽量用泛型。区别就在于机制作用时机不同,不是所有情况都可以用泛型在编译的时候确定。

// 如此一来,之前学过的所有的集合类型,都可以放到接口类型
// 1 数组
var a [3]Duck
a[1]=PDuck{}
a[2]=TDuck{}

// 2 切片
var a []Duck = make([]Duck, 3)

// 3 map
var a map[string]interface{} =  make(map[string]interface{}) 
a["name"] = "yangyi"
a["age"] = 18

// 总结: 虽然放着很开心,但是用着就需要断言,就不行了,哈哈。。。

二、接口的嵌套与实现多个接口

1 实现多个接口

书写完多个接口中的所有方法,便会自动实现几个接口。一旦转到某个接口,只能使用接口的方法,自身属性和自身方法需要类型断言后才能使用。

// 1 实现多个接口
type Duck interface {
	speak()  //speak()方法
	run()
}

type Animal interface {
	eat()
	sleep()
}

//定义一个唐老鸭结构体
type TDuck struct {
	name string
	sex string
	age int
	wife string
}

//唐老鸭实现Duck接口
func (p TDuck)speak()  {
	fmt.Println("唐老鸭说人话,唐老鸭子名字叫",p.name)
}
func (p TDuck)run()  {
	fmt.Println("唐老鸭人走路,唐老鸭子名字叫",p.name)
}

//唐老鸭实现Animal接口
func (p TDuck)sleep()  {
	fmt.Println("唐老鸭说人话,唐老鸭子名字叫",p.name)
}
func (p TDuck)eat()  {
	fmt.Println("唐老鸭人走路,唐老鸭子名字叫",p.name)
}

2 接口嵌套

// 目的: 就是为了少些一点接口【类似于面向对象的父类】
type Animal interface {
	eat()
	sleep()
}

type Duck interface {
	Animal
	speak()
	run()
}

type Cat interface {
	Animal
	speak()
	run()
}

// 定义普通鸭子结构体
type PDuck struct {
	name string
	sex string
	age int
}

// 实现duck接口
func (p PDuck)speak()  {

}
func (p PDuck)run()  {

}
func (p PDuck)sleep()  {

}
func (p PDuck)eat()  {

}

3 接口的零值

var a Animal   //nil 是引用类型 a就存2值,一个是类型,一个是指向该类型的指针
fmt.Println(a)

在Go语言中,布尔类型的零值(初始值)为 false,数值类型的零值为 0,字符串类型的零值为空字符串"",而指针、切片、映射、通道、函数和接口的零值则是 nil。

标签:fmt,接口,第五篇,鸭子,duck,Println,唐老鸭
From: https://www.cnblogs.com/yangyi215/p/17284373.html

相关文章

  • Postman测试文件上传接口
         定义请求方式和请求路径请求体选择bodybody下选择form-data在参数中输入filekey值输入完file后,在下拉框中选择file此时value会显示一个SelectFiles按钮,点击按钮即可打开我的电脑并选择需要上传的文件点击发送请求即可如何该接口需要请求头......
  • MyBatis-Spring包自动扫描MyBatis Mapper接口并将其注册为Spring Bean
    学习spring整合mybatis时,写SQL语句的Mapper接口明明没有任何被spring接管的痕迹(前面没有注解)但在serviceimpl类中却可以被自动装载。 BookDao.java(mapper接口类):packagecom.itheima.dao;importcom.itheima.domain.Book;importorg.apache.ibatis.annotations.Delete;imp......
  • (第五篇)富比较__gt__、__ge__、__lt__、__le__、__eq__、__ne__
    摘要:这些方法被称为“富比较”方法,是因为它们可以用于实现同类对象进行“比较”。这些方法的触发机制是在实例对象之间进行比较时自动调用。例如,如果有两个实例对象a和b,当执行a<b时,Python会自动查找a的类定义中是否实现了__lt__方法,如果有,则调用该方法进行比较。 一、__gt__......
  • 使用drf的序列化类实现增删改查接口
    目录什么是DRF安装DRF基于原生创建五个接口基于rest_framework的增删改查查询多条数据流程创建表创建序列化类创建视图类增加路由查询单条数据序列化类不变视图类定义对象新增路由新增一条数据序列化类视图类修改一条数据视图类删除一条数据序列化之钩子函数校验局部钩子全局钩子......
  • 微店商品详情接口,微店商品数据接口,微店商品优惠券接口封装代码教程
    业务场景:作为全球最大的B2C电子商务平台之一,微店平台提供了丰富的商品资源,吸引了大量的全球买家和卖家。为了方便开发者接入微店平台,微店平台提供了丰富的API接口,其中商品详情接口是非常重要的一部分。大家有探讨稳定采集微店整站实时商品详情数据接口,通过该接口开发者可以更......
  • 脑干软件接口实现
    接口分析今天写了一个删除用户运动指数的接口,运动指数包括了两个属性,一个每周运动次数和每次运动时间,我们需要做的就是把这两个字段清空,因为这个字段在user表中,同时我们删除他的时候不能把其他的属性删除,所以我们就不能直接使用delete方法,而是删除再添加再修改。问题与解决重......
  • JNDI(Java Naming and Directory Interface–Java命名和目录接口)
    JNDI(JavaNamingandDirectoryInterface,Java命名和目录接口)为应用程序提供了一种通过网络访问远程服务的方式。本节我们学习如何通过JNDIAPI注册和访问JDBC数据源对象。读者如果需要了解更多JNDI相关细节,则可参考JNDI规范文档。JNDIAPI的命名服务可以把一个逻辑名称和一个具......
  • python接口自动化pytest+yaml+allure
    简介分层common公共层data数据层test层+main文件其中pytest框架使用pytest.ini全局配置和conftest.py夹具test层下载对于的安装包编写对于的用例实现参数化编写对于的fixture和pytest全局配置常用pytest执行方法main方法:pytest.main(['-vs','-n2'])console:py......
  • 免费的翻译接口
     有道 示例 http://fanyi.youdao.com/translate?&doctype=json&type=AUTO&i=计算http://fanyi.youdao.com/translate?&doctype=json&type=ZH_CN2EN&i=计算http://fanyi.youdao.com/translate?&doctype=json&type=ZH_CN2KR&i=计算 返回的数据......
  • SpringBoot 服务接口限流-AOP令牌桶
    前言在开发高并发系统时有三把利器用来保护系统:缓存、降级和限流。限流可以认为服务降级的一种,限流通过限制请求的流量以达到保护系统的目的。一般来说,系统的吞吐量是可以计算出一个阈值的,为了保证系统的稳定运行,一旦达到这个阈值,就需要限制流量并采取一些措施以完成限制流量的目的......