Go Web编程实战(5)----面向对象编程(二)

简介: Go Web编程实战(5)----面向对象编程(二)

接口


使用了接口实现了多态与继承,我们也应该详细了解接口的使用方式。


接口(interface)类型是对其他类型行为的概括与抽象。接口定义了一组方法,但是不包含这些方法的具体实现。


本质上接口依旧是一个类型,确切的说,是指针类型。如果一个类型实现了某个接口,则所有使用这个接口的地方都支持这种类型的值。


需要注意的是,如果实现接口的类型支持相等运算,那么可以比较,否则会报错。示例如下:

func main() {
  var var1,var2 interface{}
  fmt.Println(var1==nil,var2==nil)
  var1,var2=6,8
  fmt.Println(var1==var2)
  var1,var2=map[string]string{},map[string]string{}
  fmt.Println(var1==var2)
}


运行之后,大家会发现,空接口变量默认值是nil。也就是第一个输出肯定是两个true。而数值不相等,第二个输出false。第三个因为map类型不支持相等运算,所以报错。



接口的赋值

Go语言的接口不支持直接实例化,但支持赋值操作,从而快速实现接口与实现类的映射。


接口赋值在Go语言中分为如下两种情况:


将实现接口的对象实例赋值给接口

将一个接口赋值给另一个接口。


将实现接口的对象实例赋值给接口

将指定类型的对象实例赋值给接口,要求该对象对应的类实现了接口要求的所有方法,否则就不能算实现了该接口。

type Number int
func (x Number) Equal(i Number) bool {
  return x == i
}
func (x Number) LessThan(i Number) bool {
  return x < i
}
func (x Number) MoreThan(i Number) bool {
  return x > i
}
func (x *Number) Multiple(i Number) {
  *x = *x * i
}
func (x *Number) Divide(i Number) {
  *x = *x / i
}
type NumberI interface {
  Equal(i Number) bool
  LessThan(i Number) bool
  MoreThan(i Number) bool
  Multiple(x Number)
  Divide(x Number)
}
func main() {
  var x Number = 8
  var y NumberI = &x
  fmt.Println(x)
  fmt.Println(y)
}


这里,我们先定义了一个Number类型以及相关方法。按照Go语言的约定,Number类型实现了NumberI接口,接下来就可以将Num类型对应的对象实例赋值给Number接口。


为什么要将&x的指针赋值给接口变量呢?这是因为Go语言会根据下面这样的非指针成员方法:

func (x Number) Equal(i Number) bool

自动生成一个新的与之对应的指针成员方法:

func (x *Number) Equal(i Number) bool{
  return (*x).Equal(i)
}


这样一来,类型*Number就存在所有NumberI接口中声明的方法了。


将接口赋值给接口

在Go语言中,只要两个接口拥有相同的方法列表,则它们就是等同的,可以互相赋值。这里,我们直接将前面的三角形修改一下。

type Triangle struct {
  Bottom float32
  Height float32
}
type Area1 interface {
  Area(x,y float32) float32
}
type Area2 interface {
  Area(x,y float32) float32
}
func (a Triangle) Area(x,y float32) float32 {
  return x*y
}
func main() {
  f1 :=Triangle{2,3}
  var f2 Area1=f1
  var f3 Area2=f2
  fmt.Println(f3)
}


如果接口Area1的方法列表是接口Area2 的方法列表的子集,则接口Area2可以赋值给接口Area1 。修改为:

type Area2 interface {
  Area(x, y float32) float32
  Sum(x, y float32) float32
}
func (a Triangle) Sum(x, y float32) float32 {
  return x + y
}
func main() {
  f1 := Triangle{2, 3}
  var f2 Area2 = f1
  var f3 Area1 = f2
  fmt.Println(f3)
}


接口查询

接口查询是在程序运行时进行的,查询是否成功,也要在运行时才能够确定。示例如下:

//语法
if filew,ok:=fileWriter.(*File);ok{
  //...
}
//示例
func main() {
  slice := make([]int, 0)
  slice = append(slice, 6, 7, 8)
  var I interface{} = slice
  if res, ok := I.([]int); ok {
  fmt.Println(res)
  fmt.Println(ok)
  }
}


上面代码中的if语句会判断接口I所指向的对象是否是[]int类型,如果是,则输出切片中的元素。


通过使用”接口类型.(type)“形式,加上switch-case语句,可以判断接口存储的类型。示例如下:

func Len(array interface{}) int {
  var length int
  if array == nil {
  length = 0
  }
  switch array.(type) {
  case []int:
  length = len(array.([]int))
  case []string:
  length = len(array.([]string))
  case []float32:
  length = len(array.([]float32))
  default:
  length = 0
  }
  fmt.Println(length)
  return length
}
func main() {
  slice := make([]int, 0)
  slice = append(slice, 6, 7, 8)
  var I interface{} = slice
  Len(I)
}


接口的组合

在Go语言中,不仅结构体与结构体之间可以嵌套,接口与接口之间也可以嵌套创造出新的接口。一个接口可以包含一个或多个其他的接口,这相当于直接将这些内嵌接口的方法列举在外层接口中一样。


如果接口的所有方法被实现,则这个接口中的所有嵌套接口的方法均可以被调用。接口的组合很简单,直接将接口名写入接口内部即可。另外,还可以在接口内部再定义自己的接口方法。示例如下:

type interface1 interface {
  PrintlnStr(s string)(a string)
}
type interface2 interface {
  PrintlnInt(s int)(a int)
}
type interface3 interface {
  interface1
  interface2
}


相关文章
|
5天前
|
Java 应用服务中间件 测试技术
深入探索Spring Boot Web应用源码及实战应用
【5月更文挑战第11天】本文将详细解析Spring Boot Web应用的源码架构,并通过一个实际案例,展示如何构建一个基于Spring Boot的Web应用。本文旨在帮助读者更好地理解Spring Boot的内部工作机制,以及如何利用这些机制优化自己的Web应用开发。
31 3
|
1天前
|
缓存 监控 安全
Django框架在大型Web应用中的架构设计与实战
【5月更文挑战第18天】Django框架在构建大型Web应用中扮演重要角色,采用分层架构(数据、业务逻辑、表示层)和多应用组织模式,结合缓存策略(如Memcached、Redis)提升性能。通过异步处理、分布式部署提高响应速度和扩展性。关注数据分区、安全设计及监控日志,确保系统高效、稳定。Django为复杂业务提供坚实基础,助力打造卓越Web系统。
18 7
|
2天前
|
JSON JavaScript 前端开发
web前端入门到实战:32道常见的js面试题,2024年最新秋招是直接面试吗
web前端入门到实战:32道常见的js面试题,2024年最新秋招是直接面试吗
|
2天前
|
JavaScript 前端开发 程序员
web前端入门到实战:32道常见的js面试题(1),面试哪些
web前端入门到实战:32道常见的js面试题(1),面试哪些
|
4天前
|
负载均衡 Go 调度
使用Go语言构建高性能的Web服务器:协程与Channel的深度解析
在追求高性能Web服务的今天,Go语言以其强大的并发性能和简洁的语法赢得了开发者的青睐。本文将深入探讨Go语言在构建高性能Web服务器方面的应用,特别是协程(goroutine)和通道(channel)这两个核心概念。我们将通过示例代码,展示如何利用协程处理并发请求,并通过通道实现协程间的通信和同步,从而构建出高效、稳定的Web服务器。
|
5天前
|
存储 人工智能 测试技术
python自动化测试实战 —— CSDN的Web页面自动化测试
python自动化测试实战 —— CSDN的Web页面自动化测试
194 0
|
5天前
|
监控 安全 Shell
记一次应急靶场实战--web1
本次应急靶机题目训练主要是为了应对接下来的护网面试和比赛,顺便提高一下自己对应急和溯源的实战能力,这里有两个逗比的事情发生,一是用D盾分析的时候,电脑环境监测到了,把要分析的马杀了,二是,发现无法使用脚本,在自己本机实验,电脑差点搞崩,还好佬在制作时候只是单次运行会占用.切记不要本机实验,一定要在虚拟机中进行测试.
|
5天前
|
数据库连接 Go 数据库
【Go 语言专栏】Go 语言中的错误注入与防御编程
【4月更文挑战第30天】本文探讨了Go语言中的错误注入和防御编程。错误注入是故意引入错误以测试系统异常情况下的稳定性和容错性,包括模拟网络故障、数据库错误和手动触发错误。防御编程则强调编写代码时考虑并预防错误,确保程序面对异常时稳定运行。Go语言的错误处理机制包括多返回值和自定义错误类型。结合错误注入和防御编程,可以提升软件质量和可靠性,打造更健壮的系统。开发人员应重视这两方面,以实现更优质的软件产品。
|
5天前
|
缓存 监控 测试技术
【Go语言专栏】使用Go语言构建高性能Web服务
【4月更文挑战第30天】本文探讨了使用Go语言构建高性能Web服务的策略,包括Go语言在并发处理和内存管理上的优势、基本原则(如保持简单、缓存和并发控制)、标准库与第三方框架的选择、编写高效的HTTP处理器、数据库优化以及性能测试和监控。通过遵循最佳实践,开发者可以充分利用Go语言的特性,构建出高性能的Web服务。
|
5天前
|
中间件 Go API
【Go 语言专栏】Go 语言中的 Web 框架比较与选择
【4月更文挑战第30天】本文对比了Go语言中的四个常见Web框架:功能全面的Beego、轻量级高性能的Gin、简洁高效的Echo,以及各自的性能、功能特性、社区支持。选择框架时需考虑项目需求、性能要求、团队经验和社区生态。开发者应根据具体情况进行权衡,以找到最适合的框架。