当前位置: 首页 > news >正文

编程语言中接口(Interface)介绍

编程语言中接口(Interface)介绍

在编程语言中,“接口”(Interface)是一种抽象类型,定义了一组方法(和属性),但不包含其具体实现。接口通常用于规定类必须实现的行为,从而实现不同类之间的一致性和可替换性。像Java和C#等静态类型语言中,接口是语言级别的构造,用于实现多态和解耦。

本文先简要介绍Java语言接口,再简要介绍Python语言中接口情况。

一、Java语言中接口

接口的特点:

  1. 接口使用 interface 关键字定义;
  2. 接口中的方法默认是 public 和 abstract 的;
  3. 接口中可以包含常量(public static final);
  4. 一个类可以实现多个接口;
  5. 接口支持多继承;

Java中的接口(Interface)是定义类行为规范的重要机制,通过接口可以实现代码的解耦、增强代码的灵活性和可维护性。接口支持多重继承、默认方法和静态方法等特性,使其在现代Java编程中发挥着重要作用。通过接口,开发者可以设计出高度模块化和可扩展的应用程序结构。

接口中的所有方法默认是public和abstract的,尽管你不需要显式地指定它们。接口可以包含常量、抽象方法、默认方法、静态方法和嵌套类型。

从Java 8开始,接口可以包含默认方法和静态方法。默认方法使用default关键字,并且可以有方法体。静态方法使用static关键字。

接口可以继承另一个接口,使用extends关键字。

接口中可以定义常量(public static final),这些常量在接口中是隐式的 public static final,即使不显式声明。

仅包含一个抽象方法的接口,被称为函数式接口,适用于Lambda表达式和方法引用。

接口的使用场景:

  • 定义规范:通过接口定义类必须实现的方法,确保不同类之间的一致性。
  • 解耦:接口与实现分离,提高代码的灵活性和可维护性。
  • 多态:通过接口引用不同的实现类对象,实现动态绑定。

下面是一个完整的Java接口示例:

①、接口Drawable.java文件

// 定义接口 Drawable
public interface Drawable {// 抽象方法 drawvoid draw();// 默认方法 descriptiondefault String description() {return "This is a drawable shape.";}// 静态方法 infostatic void info() {System.out.println("Drawable interface provides a draw method.");}
}

②、实现接口的类 Circle.java文件

// 实现接口的类 Circle
public class Circle implements Drawable {private double radius;public Circle(double radius) {this.radius = radius;}// 实现 draw 方法@Overridepublic void draw() {System.out.println("Drawing a circle with radius " + radius);}// 重写默认方法 description@Overridepublic String description() {return "Circle with radius " + radius;}
}

③、实现接口的类 Rectangle.java文件

// 实现接口的类 Rectangle
public class Rectangle implements Drawable {private double width;private double height;public Rectangle(double width, double height) {this.width = width;this.height = height;}// 实现 draw 方法@Overridepublic void draw() {System.out.println("Drawing a rectangle with width " + width + " and height " + height);}// 使用默认的 description 方法
}

④、主类用于测试InterfaceDemoA.java文件

// 主类用于测试
public class InterfaceDemoA {public static void main(String[] args) {// 创建 Drawable 接口的实现类对象Drawable circle = new Circle(5.0);Drawable rectangle = new Rectangle(4.0, 6.0);// 调用 draw 方法circle.draw();       // 输出: Drawing a circle with radius 5.0rectangle.draw();    // 输出: Drawing a rectangle with width 4.0 and height 6.0// 调用默认方法 descriptionSystem.out.println(circle.description());       // 输出: Circle with radius 5.0System.out.println(rectangle.description());    // 输出: This is a drawable shape.// 调用静态方法 infoDrawable.info();  // 输出: Drawable interface provides a draw method.// 多态示例Drawable[] shapes = {circle, rectangle};for (Drawable shape : shapes) {shape.draw();}// 输出:// Drawing a circle with radius 5.0// Drawing a rectangle with width 4.0 and height 6.0}
}

说明

接口 Drawable:

  • 定义了一个抽象方法 draw(),所有实现类必须提供具体的绘制实现。
  • 提供了一个默认方法 description(),返回图形的描述信息。
  • 提供了一个静态方法 info(),用于输出接口的信息。接口可以包含静态方法,这些静态方法(Static Methods)属于接口本身,而不是实现类。

类 Circle:

  • 实现了 Drawable 接口,提供了 draw() 方法的具体实现,用于绘制圆形。
  • 重写了默认方法 description(),提供更具体的描述。

类 Rectangle:

  • 实现了 Drawable 接口,提供了 draw() 方法的具体实现,用于绘制矩形。
  • 继承了接口的默认 description() 方法,未进行重写。

主类 InterfaceDemo:

  • 创建了 Circle 和 Rectangle 对象,并通过 Drawable 接口引用调用 draw() 方法,展示了多态性。
  • 调用了接口的默认方法 description(),分别展示了不同实现类的行为。
  • 调用了接口的静态方法 info()。
  • 使用一个 Drawable 类型的数组存储不同的图形对象,并通过循环调用 draw() 方法,进一步展示多态性。

输出结果

Drawing a circle with radius 5.0
Drawing a rectangle with width 4.0 and height 6.0
Circle with radius 5.0
This is a drawable shape.
Drawable interface provides a draw method.
Drawing a circle with radius 5.0
Drawing a rectangle with width 4.0 and height 6.0

二、Python语言中接口

Python不像Java或C#那样在语言层面上明确区分接口,但通过抽象基类(Abstract Base Classes, ABCs)、协议(Protocols)以及鸭子类型(Duck Typing)等特性,Python开发者可以灵活地实现接口概念。这些方式方法不仅保留了Python的动态特性和灵活性,还提供了结构化和可维护的代码组织方式。

1. 抽象基类(Abstract Base Classes, ABCs)实现接口

概述

抽象基类(ABCs)是Python abc 模块提供的一种机制,用于定义抽象类和抽象方法。抽象基类可以包含抽象方法(没有实现的方法),任何继承自抽象基类的子类必须实现所有的抽象方法,才能被实例化。这类似于Java中的接口,强制子类遵循特定的行为规范。

优点

  • 强制实现:确保子类实现所有抽象方法,提供一致的接口。
  • 文档和结构:清晰地定义了类的接口,有助于代码的组织和理解。

示例

假设我们要创建一个图形绘制系统,定义一个抽象基类 Shape,要求所有子类实现 draw 方法。

from abc import ABC, abstractmethod# 定义抽象基类 Shape
class Shape(ABC):@abstractmethoddef draw(self):"""绘制图形的方法"""pass@abstractmethoddef area(self):"""计算图形面积的方法"""pass# 实现抽象基类的子类 Circle
class Circle(Shape):def __init__(self, radius):self.radius = radiusdef draw(self):print(f"Drawing a circle with radius {self.radius}")def area(self):return 3.14159 * self.radius ** 2# 实现抽象基类的子类 Rectangle
class Rectangle(Shape):def __init__(self, width, height):self.width = widthself.height = heightdef draw(self):print(f"Drawing a rectangle with width {self.width} and height {self.height}")def area(self):return self.width * self.height# 主程序
def main():shapes = [Circle(radius=5),Rectangle(width=4, height=6)]for shape in shapes:shape.draw()print(f"Area: {shape.area()}")if __name__ == "__main__":main()

解析

1. 抽象基类 Shape:

  • 使用 ABC 作为基类,标识这是一个抽象基类。
  • 定义了两个抽象方法 draw 和 area,所有子类必须实现这两个方法。

2.子类 Circle 和 Rectangle:

  • 实现了抽象方法 draw 和 area,提供具体的实现细节。
  • 可以实例化,因为所有抽象方法都已实现。

3.主程序 main:

  • 创建了 Circle 和 Rectangle 对象。
  • 通过多态调用 draw 和 area 方法。

输出

Drawing a circle with radius 5
Area: 78.53975
Drawing a rectangle with width 4 and height 6
Area: 24

2. 协议(Protocols)实现接口

概述

协议(Protocols)是Python typing 模块在Python 3.8及以上版本中引入的一种机制,用于定义“结构性子类型”。与抽象基类不同,协议不需要显式继承,任何类只要实现了协议中定义的方法和属性,就被视为遵循该协议。这与静态类型检查工具(如 mypy)配合使用时特别有用。

优点

  • 无需继承:实现协议的类不需要继承自协议基类,提高了灵活性。
  • 类型检查:结合静态类型检查工具,提高代码的类型安全性。
  • 灵活性:适应Python的动态类型特性,支持更灵活的接口定义。

示例

继续使用图形绘制系统的例子,使用协议定义接口。

from typing import Protocol
import math# 定义协议 ShapeProtocol
class ShapeProtocol(Protocol):def draw(self) -> None:...def area(self) -> float:...# 实现协议的类 Circle
class Circle:def __init__(self, radius):self.radius = radiusdef draw(self):print(f"Drawing a circle with radius {self.radius}")def area(self):return math.pi * self.radius ** 2# 实现协议的类 Rectangle
class Rectangle:def __init__(self, width, height):self.width = widthself.height = heightdef draw(self):print(f"Drawing a rectangle with width {self.width} and height {self.height}")def area(self):return self.width * self.height# 使用协议的函数
def render_shape(shape: ShapeProtocol):shape.draw()print(f"Area: {shape.area()}")# 主程序
def main():shapes = [Circle(radius=5),Rectangle(width=4, height=6)]for shape in shapes:render_shape(shape)if __name__ == "__main__":main()

解析

1.协议 ShapeProtocol:

  • 使用 Protocol 定义接口,包含 draw 和 area 方法的声明。
  • 没有提供具体实现。

2.类 Circle 和 Rectangle:

  • 实现了 draw 和 area 方法。
  • 不需要继承自 ShapeProtocol,但它们遵循该协议。

3.函数 render_shape:

  • 接受一个遵循 ShapeProtocol 的对象。
  • 调用 draw 和 area 方法。

4.主程序 main:

  • 创建了 Circle 和 Rectangle 对象。
  • 通过 render_shape 函数调用,实现多态。

运行输出

Drawing a circle with radius 5
Area: 78.53981633974483
Drawing a rectangle with width 4 and height 6
Area: 24

3. 鸭子类型(Duck Typing)实现接口

概述

鸭子类型是Python的一种编程风格,基于“如果它看起来像鸭子、走起来像鸭子、叫起来像鸭子,那么它就是鸭子”的理念。在这种模式下,类型检查不依赖于对象的实际类型,而是依赖于对象是否实现了所需的方法和属性。这种方法不需要显式定义接口或继承自特定基类,使代码更加灵活和简洁。

优点

  • 高灵活性:无需预先定义接口或继承关系,适应动态变化的需求。
  • 简洁性:代码更简洁,无需额外的抽象层。
  • 快速开发:适合快速开发和原型设计。

缺点

  • 缺乏静态检查:容易导致运行时错误,尤其是在大型项目中。
  • 可维护性较低:接口规范不明确,可能导致代码难以理解和维护。

示例

使用鸭子类型实现图形绘制系统,不使用任何抽象基类或协议。

import math# 实现绘制函数
def render_shape(shape):shape.draw()print(f"Area: {shape.area()}")# 类 Circle
class Circle:def __init__(self, radius):self.radius = radiusdef draw(self):print(f"Drawing a circle with radius {self.radius}")def area(self):return math.pi * self.radius ** 2# 类 Rectangle
class Rectangle:def __init__(self, width, height):self.width = widthself.height = heightdef draw(self):print(f"Drawing a rectangle with width {self.width} and height {self.height}")def area(self):return self.width * self.height# 类 Triangle
class Triangle:def __init__(self, base, height):self.base = baseself.height = heightdef draw(self):print(f"Drawing a triangle with base {self.base} and height {self.height}")def area(self):return 0.5 * self.base * self.height# 主程序
def main():shapes = [Circle(radius=5),Rectangle(width=4, height=6),Triangle(base=3, height=4)]for shape in shapes:try:render_shape(shape)except AttributeError as e:print(f"Error: {e}")if __name__ == "__main__":main()

解析

1.函数 render_shape:

  • 不关心传入对象的类型,只调用 draw 和 area 方法。
  • 如果对象缺少某个方法,会在运行时抛出 AttributeError。

2.类 Circle 和 Rectangle:

  • 实现了 draw 和 area 方法,符合 render_shape 的要求。

3.类 Triangle:

  • 实现了 draw 和 area 方法,符合 render_shape 的要求。

4.主程序 main:

  • 创建了 Circle、Rectangle 和 Triangle 对象。

输出

Drawing a circle with radius 5
Area: 78.53981633974483
Drawing a rectangle with width 4 and height 6
Area: 24
Drawing a triangle with base 3 and height 4
Area: 6.0

附录

计算机科学中的接口(Interface)介绍 https://blog.csdn.net/cnds123/article/details/140016760

Java接口介绍 https://blog.csdn.net/cnds123/article/details/130618885

相关文章:

编程语言中接口(Interface)介绍

编程语言中接口(Interface)介绍 在编程语言中,“接口”(Interface)是一种抽象类型,定义了一组方法(和属性),但不包含其具体实现。接口通常用于规定类必须实现的行为&…...

算法学习之贪心算法

前言 记录一下,免得又又忘了 贪心算法 在刚接触的时候,我一直觉得贪心和动态规划有相似之处,但做过的题目看,贪心似乎不用迭代...

【jvm】垃圾回收的优点和原理

目录 1. 说明2. 优点3. 原理3.1 发现无用对象3.2 回收无用对象所占用的内存 4. 回收算法4.1 标记-清除算法4.2 复制算法4.3 标记-整理算法4.4 分代收集算法 1. 说明 1.JVM(Java虚拟机)垃圾回收是Java语言的一大特性,它自动管理内存&#xff…...

YOLO系列发展历程:从YOLOv1到YOLO11,目标检测技术的革新与突破

文章目录 前言一、YOLOv1:单阶段目标检测的开端二、YOLOv2:更精准的实时检测三、YOLOv3:阶梯特征融合四、YOLOv4:性能和速度的新平衡五、YOLOv5:易用性和扩展性的加强六、YOLOv6:工业部署的利器七、YOLOv7&…...

深入浅出:序列化与反序列化的全面解析

文章目录 1. 引言2. 什么是序列化?2.1 为什么需要序列化? 3. 什么是反序列化?3.1 反序列化的重要性 4. 序列化与反序列化的实现4.1 JSON (JavaScript Object Notation)4.2 XML (eXtensible Markup Language)4.3 Protocol Buffers (Protobuf)4…...

word实践:正文/标题/表图等的共用模板样式设置

说在前面 最近使用word新建文件很多,发现要给大毛病,每次新建一个word文件,标题/正文的字体、大小和间距都要重新设置一遍,而且每次设置这些样式都忘记了参数,今天记录一下,以便后续方便查看使用。现在就以…...

Blender中使用BlenderGIS插件快速生成城市建筑模型

导入下载 BlenderGIS 插件 去github上下载其压缩包,地址如下: https://github.com/domlysz/BlenderGIS 在BlenderGIS中导入这个插件压缩包: 点击上方菜单栏的编辑,点击偏好设置 在插件>从磁盘安装中导入刚刚下载的压缩包 可…...

【单元测试】单元测试的重要性

1一些错误的认识 在实际的单元测试过程中总会有一些错误的认识左右着我们,使之成为单元测试最大的障碍,在此将其一一分析如下: 它太浪费时间了,现在要赶进度,时间上根本不允许,或者随便做做应付领导。 …...

Codeforces Round 992 (Div. 2)

这场cf只在b卡了一下,因为b真是犯蠢了,我以为会向下取整,结果是完全就不取整,或者说是向上取整,卡了我半个小时,要不是紧急看了题一下,昨天那场就毁了 话不多说,直接开讲 A. Game …...

el-table一键选择全部行,切换分页后无法勾选

el-table一键全选,分页的完美支持 问题背景尝试解决存在问题问题分析 解决方案改进思路如下具体代码实现如下 问题背景 现在有个需求,一个表格有若干条数据(假设数量大于20,每页10条,保证有2个以上分页即可)。 现在需要在表格上方…...

负载均衡最佳实践及自定义负载均衡器

文章目录 负载均衡最佳实践及自定义负载均衡器一、负载均衡概述二、轮询负载均衡器(一)理论介绍(二)Java 实现示例(三)关键步骤(四)流程图 三、随机负载均衡器(一&#x…...

大模型 LMDeploy 量化部署

1 模型部署 定义: 在软件工程中,部署通常指的是将开发完毕的软件投入使用的过程。在人工智能领域,模型部署是实现深度学习算法落地应用的关键步骤。简单来说,模型部署就是将训练好的深度学习模型在特定环境中运行的过程。 场景…...

算法设计5_分支限界法

分支限界法 分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树,裁剪那些不能得到最优解的子树以提高搜索效率。 步骤: ① 定义解空间(对解编码); ② 确定解空间的树结构; ③ 按BFS等方式搜索: a.每个活…...

2025年人工智能专业可以考哪些证书呢?

人工智能是目前全球热门的专业领域之一,随着人工智能应用范围的不断扩大,越来越多的人开始关注人工智能相关证书的获取。那么,人工智能专业可以考什么证书呢?本文将为大家介绍人工智能相关证书的种类。 人工智能机器视觉应用工程师…...

仿真技术助力高尔夫球打破传统设计局限,实现球杆强大的功能

Altair近日宣布与业内领先的高尔夫装备制造商 Cleveland Golf 开展合作,以设计新款 HiBore XL 球杆。借助 Altair 先进的仿真与设计技术,Cleveland Golf 不断刷新高尔夫装备的行业标准,并在球杆产品设计方面实现突破。 Cleveland Golf 借助 A…...

微前端架构学习笔记

前言 之前遇到过一个需求,有两个项目分别由两个不同的部门负责,不同技术栈,不同代码仓库: A 项目是官网,负责展示产品亮点等信息,有多个入口可以进入 B 项目中的不同页面。B 项目是业务线,负责…...

DApp开发:从合约到系统快速上线解决方案

在区块链技术迅猛发展的今天,去中心化应用(DApp)作为区块链的一项重要应用,已经吸引了众多开发者和企业的关注。与传统应用程序不同,DApp依托于区块链的去中心化特点,实现了透明、安全、不可篡改等优势&…...

react 中 useState 中的 set 方法异步解决

使用 useEffect 监听状态的改变。 一、异步特性 在批量处理状态更新时,用以提高性能。 二、异步解决 使用useEffect来处理更新后的状态,useEffect钩子在组件渲染后执行,并且会在依赖项(第二个参数)发生变化时重新执…...

UAC2.0 speaker——带反馈端点的 USB speaker(16bit 单声道)

UAC2.0 speaker 系列文章 UAC2.0 speaker——单声道 USB speaker(16bit) UAC2.0 speaker——类特殊请求 UAC2.0 speaker——音量控制 UAC2.0 speaker——多采样率支持 UAC2.0 speaker——24/32bit 支持 UAC2.0 speaker——speaker 数据传输 UAC2.0 speaker——同时支持 16bi…...

docker的简单使用

文章目录 docker简介docker架构镜像和容器镜像有关的常用命令容器相关常用命令 docker简介 Docker是一个开源的应用容器引擎,基于Go语言并遵从Apache2.0协议开源。 Docker可以让开方子打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到…...

XML Group端口详解

在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂&#xff…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...

网络编程(UDP编程)

思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...