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

假面与演员:到底是接口在使用类,还是类在使用接口?编程接口与物理接口的区别又是什么?

前言:本篇文章解释了接口学习过程中的2个常见问题,一个是“为什么是类在使用接口”,另一个一个是“编程接口与物理接口的差异源于所处的抽象层次和交互模式的不同”,旨在揭示编程接口的本质。

Part1.是类在使用接口

当学习接口时,很多人都会告诉你“是类在使用接口”。但是我们观察接口的运用方式,会发现我们常常是用接口类型的变量来接收类的实例,并使用类中的具体方法。这不禁让我们产生疑问:到底是接口在使用类,还是类在使用接口?

先说结论:“是类在使用接口”,而不是接口在使用类。下面由我来为大家揭示控制反转的微妙之处。

一. 表象:为什么“看起来像接口在使用类”?

1. 代码的直观表现

当用接口类型的变量调用方法时,代码的书写形式确实像是“接口在操作类”:

// 接口类型变量
Flyable obj = new Bird();
obj.fly(); // 看似接口调用了 Bird 的方法

这里 Flyable 类型的变量 obj 调用了 fly() 方法,而实际执行的是 Bird 类的实现。这种写法容易让人产生“接口主动使用类”的错觉。

2. 直觉误区来源

  • 语法焦点:代码的书写顺序(先声明接口变量,再调用方法)暗示了“接口是主语”。

  • 隐藏动态绑定:编译时只知道 obj 是 Flyable 类型,但运行时实际调用哪个类的 fly() 是动态决定的。这种“延迟绑定”掩盖了类的主动性


二. 本质:假面与演员。。

1. 接口是“面具”,类是“演员”

接口类型的变量更像是一个角色标签。它不关心背后具体是哪个类,只关心这个类是否“戴上了面具”(实现了接口)。观众们(我们)看到并记住的是这个假面(接口),真正在表演的是演员(类)。

真正的执行者是类自身的方法:

// 逻辑拆解:
Flyable obj = new Bird();  // 类主动“戴上面具”(实现接口)
obj.fly();                // 面具下的演员(Bird)在表演

2. 接口的“被动性”

在运行时,JVM/编译器会根据对象实际类型调用对应方法,与接口无关。

接口没有能力“主动使用”任何类,它只是:

  • 定义规范:列出需要实现的方法清单。

  • 提供类型标识:允许其他代码以统一的方式操作不同类。


三. 纠正思维:重新理解主动权!

1. 类才是行为的拥有者

接口只是强制类公开某些能力,但能力的具体实现完全由类决定

例如:

interface Weapon {void attack();
}class Sword implements Weapon {public void attack() { System.out.println("挥剑"); } // 类的主动性
}class Gun implements Weapon {public void attack() { System.out.println("开枪"); } // 类的主动性
}

无论是 Sword 还是 Gun,它们的 attack() 逻辑由类自身定义,接口无法干预

当通过接口调用方法时,本质是其他代码(如调用方)通过接口的抽象层间接使用类,而非接口本身在操作类。例如:

// 一个外部系统通过接口调用类
class GameEngine {void useWeapon(Weapon weapon) {weapon.attack(); // 实际调用 Sword.attack() 或 Gun.attack()}
}

这里 GameEngine 是主动调用者,接口只是传递调用的媒介

2. 生活类比修正

假设你是一个餐厅老板,你定义了一份“厨师岗位职责”(接口):职责要求:会做菜、会清洁厨房。

具体的厨师 (类):张三、李四各自以自己的方式实现这些职责。

当顾客点菜时,他们通过“厨师岗位”这个抽象概念获得服务,但实际做菜的是张三或李四。岗位职责(接口)没有能力做菜,它只是确保张三李四具备做菜能力


四、总结

你的困惑揭示了编程中“控制反转”的微妙之处:

  • 直觉认为:接口是“控制者”(因为它规定了类必须做什么)。

  • 实际逻辑:接口是“被控制者”(通过实现接口,主动向外界暴露能力)。

这种反直觉的设计恰恰是面向对象编程的威力所在——通过抽象层解耦调用方和实现方,让系统更灵活。理解这一点后,你会意识到:不是接口在使用类,而是类通过接口向 外界 宣告“我能做什么”

Part2. 编程接口与物理接口的区别

关于接口的知识,我们可能还有一些疑惑之处:

在java中,类如果实现了接口,那么接口类型的变量就可以操控对象的函数执行,感觉像是接口和对象在互动,一共有两个角色;而物理上的接口,比如可以用鼠标操控电脑,这就感觉是对象1与对象2在互动,它们之间的USB接口是互动的桥梁,这之中一共有三个角色

为什么我们看到的只有接口和对象在互动?编程接口与物理接口的区别又是什么?

一、两者模式?三者模式!

接口作为规范,约束了对象必须提供哪些方法,但不参与实际交互过程。动态绑定机制隐藏了接口的被动性,让你感觉是接口和对象在“互动”的两者模式,但实际是对象在主动向外界提供服务

在编程中,完整的交互确实涉及三个角色,它们分别是对象、接口、外界其中外界既可以是我们这种调用者,也可以是其他调用该方法的代码

以刚刚“生活类比修正”的比喻为例,编程接口就相当于一张岗位招聘,类就相当于具体的厨师,食客就是此处的外界。厨师按照招聘要求前来工作,做好菜品给食客品尝也展示了自己的实力。

三者的交互逻辑:(编程接口)

  1. 对象通过接口向外界宣告能力
    类实现接口时,相当于对象对外界宣告:“我能提供这些服务!”(如 Bird 实现 Flyable 接口后,宣告自己能飞)。
    主动性:对象的实现是服务提供的基础。

  2. 外界通过接口使用对象
    调用方(外界)无需知道对象的具体类型,只需依赖接口定义的方法(如 void makeItFly(Flyable flyableObj))。
    间接性:接口作为“中间人”确保调用的合法性,但不参与实际执行

  3. 接口作为契约约束双方

    • 对对象:必须实现接口方法。

    • 对外界:只能调用接口定义的方法。

交互流程图:

外界(调用方) —— 通过接口 ——→ 对象↑                     ↓←— — 实际执行结果 ——  ←—

二、核心区别

我们再来看一下物理接口的三者模式:

  • 参与者:设备A(如鼠标)、设备B(如电脑)、接口标准(如USB协议 + 物理接口)。

  • 互动逻辑
    物理接口是独立存在的中间层,它同时包含:

    • 逻辑规范:定义数据传输格式(如USB协议规定电压、信号时序)。

    • 物理实体:接口形状(如Type-C插头)、线缆、电路。
      设备A和B必须共同遵守接口规范,并通过物理接口交换数据。此时接口既是“约束者”又是“传输通道”

编程接口和物理接口都有约束的作用,为什么只有物理接口有信息传输的职责?(编程接口与物理接口的核心区别):

1. 抽象层次的分离
  • 编程接口:属于纯逻辑层,仅通过代码约定行为,无需物理载体。

  • 物理接口:需要逻辑与物理的统一,既要定义交互规则(如协议),又要实现物理信号传输

2. 交互复杂性的需求
  • 物理设备间的交互需要严格的兼容性(如电压匹配、插头尺寸),因此必须通过独立的接口层协调。

  • 编程中的接口即便隐藏了外界角色的存在,也足够支撑多态性

3. 设计目标的差异
  • 编程接口:目标是解耦(调用方无需关心具体实现类)。

  • 物理接口:目标是互联(让不同设备能够物理连接并通信)。


“用接口类型变量调用方法”的本质是:类通过接口向外界提供服务,而调用方通过接口的抽象层使用这些服务。接口是被动的约束者,类才是主动的提供者(调用者是外界)。 这种设计让代码更灵活,但抽象层带来的“间接性”会让人产生方向混淆——这是学习抽象思维的必经之路,而非认知障碍。

让我们在学习编程的道路上继续成长吧!本期分享完毕,感谢大家的支持Thanks♪(・ω・)ノ

http://www.lryc.cn/news/538905.html

相关文章:

  • 数据结构——Makefile、算法、排序(2025.2.13)
  • 算法之 跳跃游戏
  • C#中的图形渲染模式
  • 二.数据治理流程架构
  • 瑞萨RA-T系列芯片ADCGPT功能模块的配合使用
  • 扩散模型中的马尔可夫链设计演进:从DDPM到Stable Diffusion全解析
  • 通俗诠释 DeepSeek-V3 模型的 “671B” ,“37B”与 “128K”,用生活比喻帮你理解模型的秘密!
  • 大模型常识:什么是大模型/大语言模型/LLM
  • iOS 中使用 FFmpeg 进行音视频处理
  • SAP-ABAP:SAP的Screen Layout Designer屏幕布局设计器详解及示例
  • 一.数据治理理论架构
  • 亲测有效!使用Ollama本地部署DeepSeekR1模型,指定目录安装并实现可视化聊天与接口调用
  • MySQL安装MySQL服务时提示Install-Remove of the Service Denied
  • (Windows | Linux)ssh访问服务器报错:no matching key exchange method found
  • Linux(centos)系统安装部署MySQL8.0数据库(GLIBC版本)
  • 有哪些滤波,原理是什么,分别在什么时候用
  • 深入解析与解决 Oracle 报错:ORA-29275 部分多字节字符20250213
  • iOS 上自定义编译 FFmpeg
  • linux-带宽性能压测-全解iperfwgetspeedtest-cli
  • 【前端学习笔记】Webpack
  • Qt——连接MySQL数据库之编译数据库驱动的方法详细总结(各版本大同小异,看这一篇就够了)
  • 【R语言】方差分析
  • 深度学习机器学习:常用激活函数(activation function)详解
  • TCP协议(Transmission Control Protocol)
  • django上传文件
  • Web 后端 请求与响应
  • 【深度解析】图解Deepseek-V3模型架构-混合专家模型(MoE)
  • 全平台搭载旭日5!科沃斯GOAT智能割草机器人全新系列正式开售
  • ORB-SLAM3的源码学习:TwoViewReconstruction通过两幅图像来实现重建
  • 基于单片机ht7038 demo