go语言interface接口继承多 态示例及定义 解析
作者:Jeff的技术栈 发布时间:2023-10-14 02:49:27
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()
}
来源:https://www.cnblogs.com/guyouyin123/p/13865340.html
猜你喜欢
- 停止mysql服务(以管理员身份,在cmd命令行下运行) net stop mysql或者在服务中停止mysql服务。使用 mysqld –
- 语法:Void header(string $string[,bool $replace=true [, int $http_respons
- 见下,把数字转成条形图、条形码的一个程序:<%Sub ShowChart(ByRef aValues,
- Go pongo2 教程展示了如何使用 pongo2 模板引擎在 Golang 中使用模板。模板引擎是一个库,旨在将模板与数据结合起来以生成
- SQL Server 2005相对于SQL Server 2000做了很大的改进,许些新特性是非常实用的。本文中将通过几个具体示例进行详细的
- 情况1:Go语言中,若在子go程中创建一个新 go程,子go程释放(销毁),新创建的go程不会随着子go程的销毁而销毁。原因:go程共享堆,
- 一直以来都对DOMDocument与 XMLHTTP 两者的区别不甚了解,今天用 eXeScope 查看了msxml6.dll 内
- 做个性休闲类项目课程材料,对这方面要求多一些,要总结方法、手法、想法等等,头大了;这里总结了一个做个性字体设计的方法,分享一下;方法是比较简
- 今天主要向大家讲述的是优化SQL Server数据库的实际操作经验的总结,同时也有对其优化的实际操作中出现的一些问题的描述,以及对SQL S
- 先看效果,实现一个图片左右摇动,在一般的H5宣传页,商家活动页面我们会看到这样的动画,小程序的动画效果不同于css3动画效果,是通过js来完
- 首先,我们需要着重介绍一些概念,以给你提供一些使这个“奇迹”得以发生的组成部分。太轻易地泄露伏笔对于讲故事来说不是个好的形式,所以那些不愿意
- Web性能优化最佳实践中最重要的一条是减少HTTP请求,它也是YSlow中比重最大的一条规则。减少HTTP请求的方案主要有合并JavaScr
- 主要代码如下: total = application("All
- XML Web Service 是在 Internet 上进行分布式计算的基本构造块。开放的标准以及对用户和应用程序之间的通信和协作的关注产
- 六、XML展望 任何一项新技术的产生都是有其需求背景的,XML的诞生是在HTML遇到不可克服的困难之后。近年来HTML在许多复杂的Web应用
- 人们对于产品设计这类事情,往往容易眼高手低,在宇宙层面上夸夸其谈,却落不了地,只能飘着。真正到了自己动手的时候,才会发现问题很多,实践和理论
- 一、背景:nginx 的log 不会自动按天备份,而且记录时间格式不统一,此程序专门解决这两个问题;二、windows 部署方式1.在 ng
- 广州4.18书友会主题的内容提纲自己参与撰写,同时还参与组织和主持。通过这次的深入参与,我发现胡晓同学能坚持下来多不容易,先赞下。由于天公不
- 介绍Zmail 使得在python3中发送和接受邮件变得更简单。你不需要手动添加服务器地址、端口以及适合的协议,zmail会帮你完成。此外,
- 代码如下:SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO /* by kudychen 2