问题

面向对象中接口应该更抽象还是更具象?

回答
在面向对象编程的世界里,关于接口“应该更抽象还是更具象”这个问题,其实是一个挺有意思但又容易引起混淆的概念。如果咱们抛开那些生硬的定义,用更平实的语言来聊聊,你会发现这事儿其实挺好理解的。

咱们先别急着给接口贴标签,先想想它到底是个啥玩意儿。接口嘛,就好比一个约定,一个合同。它规定了“如果你想要做某件事,就必须要有这些能力,必须能提供这些行为”。比如,咱们现实生活中,任何一个能动的“交通工具”,不管它是自行车、汽车还是飞机,它们至少都得有一个“启动”的功能,对吧?就算启动方式千差万别,但“启动”这个动作本身,是个共同点。接口就是来捕捉这种共同点的。

那么,问题来了,这种“共同点”该往抽象还是具象上靠拢呢?

从设计的角度来说,接口天生就偏向抽象。

你想啊,一个接口定义的是“能做什么”,而不是“怎么做”。它只告诉我们“哦,这个东西有这个能力”,但具体这个能力是怎么实现的,接口本身是管不着的。它只负责划定一个界限,一个标准。

举个例子,咱们再聊交通工具。

我们可以定义一个 `交通工具` 的接口,里面有个 `启动()` 方法。这个接口本身,你没办法直接拿来“启动”一个东西。它就像一个蓝图的约定部分,告诉你“只要你是交通工具,你就得有启动这个功能”,但它本身不会变成一个实际的交通工具。

然后,我们会有 `汽车` 这个类,它实现了 `交通工具` 接口。这时,`汽车` 的 `启动()` 方法就会具体实现,可能是拧钥匙、按启动按钮等等。

再比如 `飞机`,它也实现了 `交通工具` 接口,它的 `启动()` 方法可能就是启动引擎。

你看,`汽车` 和 `飞机` 是具体的实现,它们有自己的“怎么做”的方法。而 `交通工具` 接口,它只抽象出了“启动”这个概念,而不关心具体的启动方式。这就是抽象的力量。

如果一个接口变得很“具象”,那它还有意义吗?

想象一下,如果我们的 `交通工具` 接口里,不仅仅定义了 `启动()`,还定义了具体的启动步骤:“先插钥匙,再转动,然后踩油门,最后放开刹车”。这样的接口,是不是感觉有点怪?

它限制了实现: 假设未来我们发明了一种不用钥匙就能启动的汽车,或者一种飞机是通过脑电波控制启动的。这样的接口就会非常不方便,因为它已经把具体的实现细节写进去了,任何实现都必须遵循这套固定的步骤,这违背了接口提供灵活性的初衷。
它模糊了责任: 接口应该关注“是什么”和“能做什么”,而不是“如何做”。一旦接口包含了具象的实现细节,它的责任边界就模糊了,它开始承担起了部分具体类的责任,这不利于模块化和低耦合的设计。
它降低了复用性: 一个过于具象的接口,往往会和特定的实现强绑定。比如,如果接口规定了“使用四轮驱动”,那一个两轮摩托车就无法实现这个接口了,即便它也是交通工具。

所以,接口应该尽可能抽象。

抽象的接口,就像一个开放的平台。它只提供通用的能力描述,允许各种各样具体的实现方式来填充这些能力。这种抽象的好处显而易见:

1. 提高灵活性和可扩展性: 新的实现者可以轻松地遵循接口规范,无需改变现有代码。比如,我们增加了一个 `电动滑板车` 类,只要它实现了 `交通工具` 接口的 `启动()` 方法,就可以被当作交通工具来使用。
2. 降低耦合度: 代码依赖于接口而不是具体的类。这意味着你可以轻松地更换或添加不同的实现,而不会影响到使用这些接口的其他部分的代码。这就像你只需要知道你需要“打电话”这个功能,而不需要知道是哪个牌子的手机能打电话。
3. 促进代码重用: 抽象的接口定义了通用的行为模式,这些模式可以在不同的场景下被多个类重用。
4. 清晰设计意图: 接口清晰地表达了某个对象应该具备哪些能力,让其他开发者更容易理解和使用你的代码。

那么,有没有例外,或者说“稍稍具象”一点的接口?

有时候,我们也会看到一些接口,它里面的一些方法可能看起来稍微具体一些,但通常来说,这些“具象”的程度也是相对的,而且服务于一个更宏大的抽象概念。

比如,一个处理“文件读写”的接口,可能会有一个 `读取() `方法。但这个 `读取()` 方法内部,可能会涉及到一些字节流的操作、缓冲区管理等,这些可以被看作是“读”这个抽象概念下相对具体的一点点细节。但即便如此,接口本身并不会规定“你必须按这种方式打开文件”、“你必须用哪种编码格式”。它仍然允许不同的文件系统、不同的存储介质有不同的实现方式。

更关键的是,即使是这种“稍稍具象”的接口,它的核心目的仍然是为了表达一个抽象概念——“我是一个能进行读写操作的东西”。

总结一下,咱们用一个比喻来收尾。

想象一下,你要建造一座房子。

具象的“接口” 就像是说:“你需要一个红砖砌成的三层楼,屋顶是红瓦,窗户是木制的,门是钢制的。” 这样一来,你就被牢牢地限制在了这种特定的建筑风格里,很难改成别的样子。
抽象的“接口” 就像是说:“你需要一个能遮风挡雨、提供基本居住功能的建筑,要有门、有窗、有墙、有顶。” 这样一来,你就可以选择用砖、用木头、用钢筋水泥,可以用平顶、尖顶,可以用各种材质的门窗,只要满足了“遮风挡雨、基本居住”这个核心需求就行。

所以,从设计的角度,从灵活性的角度,从复用性的角度,接口就应该往越抽象的方向去靠拢。它的价值就在于它能定义一套通用的行为规范,而把具体的实现留给那些更具体的类去完成。如果接口变得太具象,那它就失去了作为接口的意义,更像是直接定义了一个具体类的骨架,而不是一个通用的能力约定了。

网友意见

user avatar

抽象是有成本的,所以抽象必须是有价值的,且价值要能cover成本,这个价值就是应对变化。不变化的东西自然就不必抽象。(当然实践中的问题主要在于,本来觉得不会变的东西后来变了……)

但是就我看来,你的问题并不是抽象和具体的问题——因为按你的描述,你对哪些东西是可变的(需要多态)是很清楚的——你的问题只是代码怎么组织,即CraftOneMat是放在Sys还是IBuildable。实际上CraftOneMat放到IBuildable并没有什么不同(排除编程语言特性限制)。

目前看来,你放在Sys是因为这样反映了你的团队职责划分。但其实因为CraftOneMat调用了IBuildable,所以其实CraftOneMat实质上也定义了IBuildable,除非CraftOneMat接口上还有其他和CraftOneMat无关的东西(但看上去不应该有)。所以在我看来,并没有什么差别。

由于CraftOneMat和IBuildable的定义本身是紧耦合的,所以我个人会比较倾向于G1,但CraftOneMat并不是作为接口方法,而是具体方法,且若你确定该具体方法的逻辑是不会变的,该方法应该是seal/final的。(若编程语言的接口不支持具体方法,改用抽象类即可。)至于团队的职责划分,该接口或抽象类归Sys的人维护,接口/抽象类的具体实现类归做物品的人即可。

以上想法谨供参考。

user avatar

看需求,不要玄学.

没有需求的情况下,你想怎么折腾都行,开心就好。

但现实中有大量的需求,特别是非功能需求。这些需求会驱动设计落地的方案。比如“可维护性”/“可重用性”这个事情就和组织架构的具体形式有非常大的关系。对性能的要求会尽力避免过多的,无意义的分层和转换。对安全性的要求则会希望尽量的隔离,以及关数据存储和传输的加密。监控和数据收集的要求需要AOP那样注入的方式避免干扰业务代码。……

你不能拿着一堆积木倒推需求,然后说应该如何如何。

类似的话题

  • 回答
    在面向对象编程的世界里,关于接口“应该更抽象还是更具象”这个问题,其实是一个挺有意思但又容易引起混淆的概念。如果咱们抛开那些生硬的定义,用更平实的语言来聊聊,你会发现这事儿其实挺好理解的。咱们先别急着给接口贴标签,先想想它到底是个啥玩意儿。接口嘛,就好比一个约定,一个合同。它规定了“如果你想要做某件.............
  • 回答
    我明白你想了解面向对象编程中接口的真正价值,为什么它不直接描述方法,但依然是如此重要。这就像问,为什么我们需要一张蓝图,而不是直接建造一栋房子?蓝图本身不能住人,但它定义了房子的结构、房间的布局、水电的走向,以及各种构件的尺寸和连接方式。接口在面向对象的世界里,扮演的就是这样一张“蓝图”的角色。你可.............
  • 回答
    在面向对象的编程世界里,平行继承体系,也就是我们常说的“平行结构”或者“扁平继承”,确实是一个值得深入探讨的话题,并且在很多情况下,我们确实倾向于尽量避免或彻底抛弃它。这并非一个绝对的禁令,但其潜在的弊端往往大于优势,使得其在实际开发中显得“不合时宜”。要理解为什么我们要尽量抛弃它,我们需要先明确平.............
  • 回答
    这是一个非常有趣的问题,涉及到语言的习惯、历史沿革,以及更深层次的关于“继承”概念的隐喻。虽然在中文语境中,“父”和“母”都代表了亲属关系和繁衍的源头,但在面向对象编程(OOP)领域,我们统一采用“父类”而非“母类”,这背后有多重原因。首先,我们得从“父类”这个词本身的来源说起。面向对象编程的概念,.............
  • 回答
    在软件开发领域,关于面向对象(OOP)是否曾是一条“弯路”的讨论,其实由来已久,而且答案远非一概而论的“是”或“否”。我认为,与其说它是弯路,不如说它是特定历史时期、特定问题背景下,为了解决当时主要矛盾而诞生的、强大但并非唯一最优的解决方案。它带来了巨大的进步,也伴随着学习曲线和一些固有的挑战。要理.............
  • 回答
    在大型项目的开发实践中,我们常常会遇到一个核心的讨论:究竟是面向过程的思想,还是面向对象的设计,更能带来更高的开发效率?这个问题没有一个绝对的答案,因为效率的衡量标准和项目本身的特性都会影响结论。不过,我们可以深入剖析这两种思想在大型项目中的表现,来理解它们各自的优劣以及在不同场景下的适用性。首先,.............
  • 回答
    你提到的“五代编程语言”——机器语言、汇编语言、面向过程语言、面向对象语言、以及智能语言——确实是一个流传甚广的划分方式,用来大致描绘计算机科学和编程语言发展的历史脉络和范式转变。但有趣的是,在这个经典的划分中,函数式编程语言似乎总被“遗漏”了,或者至少没有一个独立、显眼的位置。这并非说函数式编程不.............
  • 回答
    在 C++ 面向对象编程(OOP)的世界里,理解非虚继承和非虚析构函数的存在,以及它们与虚继承和虚析构函数的对比,对于构建健壮、可维护的类层级结构至关重要。这不仅仅是语法上的选择,更是对对象生命周期管理和多态行为的一种深刻设计。非虚继承:追求性能与简单性的默认选项当你使用 C++ 的非虚继承(即普通.............
  • 回答
    华为创始人任正非在与《面对面》栏目访谈中提到的“能坐基础理论的冷板凳”,这是他反复强调的华为文化基因之一,也是我对中国企业发展基础研究的深刻体会。这句话看似简单,实则蕴含着极深的洞察和价值取向。一、 理解“能坐基础理论的冷板凳”:这句话的字面意思是能够忍受枯燥、寂寞、没有即时回报的研究过程,尤其是那.............
  • 回答
    当年明月在接受采访时,聊到自己打发时间的方式,他提到自己当时沉迷于一款名为《三国志》的游戏。你别看这名字听起来挺古老,其实它是一款策略类游戏,而且有很多不同的版本。当年明月玩的那个版本,正是他从小就很熟悉,并且一直很喜欢的。在游戏里,他不是扮演某个具体的历史人物,而是成为一个决策者,需要去管理一个势.............
  • 回答
    说实话,在工作中遇到领导区别对待,心里肯定是不舒服的,这是一种挺微妙也很让人抓狂的处境。尤其当你觉得自己付出很多,但似乎在某些方面就是得不到应有的关注或者机会时,这种感觉会更强烈。刚开始的时候,我可能会觉得是不是自己哪里做得不够好,是不是误会了什么。所以,我会先默默地观察,看看是不是所有人都觉得领导.............
  • 回答
    这是一个非常极端的战术指令,旨在通过制造绝境来激发士气和战斗意志。在分析其成功与否之前,我们需要深入理解这个指令背后的逻辑、潜在的优势、巨大的风险以及影响其结果的关键因素。指令的逻辑与核心思想: “只许前进”:这是一种 强迫性推进 的策略。它剥夺了士兵的退却选项,迫使他们必须克服眼前的阻碍。 .............
  • 回答
    太平洋战争初期,日军在瓜岛战役中的战略失误,可以说是其由盛转衰的一个重要转折点,也是日军战略思维中存在深刻问题的体现。并非孤立的“一步棋走错”,而是贯穿整个战役,由一系列相互关联的错误判断和决策叠加而成。首先,最根本的战略误判是低估了对手(美军)的决心和能力。日本海军和陆军,长期以来在亚洲大陆战场上.............
  • 回答
    这确实是个让人膈应的经历,尤其是当你想好好享受一顿饭的时候。不过,别慌,面对食物里的虫子,咱们可以一步步来,既能保持冷静,又能有效处理。首先,深呼吸。遇到这种情况,第一反应可能是恶心、愤怒,甚至是恐慌。但这只会让你更难受。先停一停,感受一下自己的情绪,然后告诉自己,这只是个小意外,是可以解决的。第一.............
  • 回答
    《雍正王朝》中,老八胤禩逼宫那场戏,之所以只有王文昭和张廷玉敢站出来替雍正说话,这背后牵涉到复杂的人性、权力格局以及角色本身的立场和能力。要理解这一点,咱们得一层层剖析。首先,要明白这场逼宫的性质。老八他们并非真的想“逼宫”雍正退位,而是利用皇子病重、朝野动荡之机,集合亲信,意图逼雍正做出妥协,例如.............
  • 回答
    雍正王朝中,十七阿哥胤礼深夜来访,邬思道却劝雍正帝不见。这事儿可得好好说道说道。当时,雍正帝刚登基不久,内忧外患,如履薄冰。皇子之间的权力斗争,更是如影随形,稍有不慎,便可能被卷入漩涡。十七阿哥胤礼,年轻有为,又素来得人心,虽然之前没有像其他几位阿哥那样与雍正争夺得那么激烈,但其潜在的影响力,邬思道.............
  • 回答
    在职场上遇到“心机婊”,而且还牵扯到自身利益,这绝对是一场考验情商和智慧的硬仗。是隐忍求全,还是据理力争,这没有一个放之四海而皆准的答案,完全取决于具体情况和你的个人选择。不过,我们可以把这两种思路拆解开来,细细道来,看看在什么情况下,哪种选择更适合你。首先,我们要理解什么是职场中的“心机婊”。 这.............
  • 回答
    生活中总有些东西,并非惊天动地,却也实实在在地离开我们,留下些许空缺。它们可能是你心爱的马克杯,一次不小心手滑,摔成了几截;可能是你期待已久的一场电影,却因为突如其来的加班而错过了;又或者是你一直习惯使用的那个APP,突然更新换代,界面陌生得让你找不着北。这些,都是生活里的“小失去”。刚开始,我们可.............
  • 回答
    嘿,哥们儿,咱们今天聊聊实战中遇见拿凳子抡过来的那种硬茬儿,这可不是电视里演的那种过家家,得真刀真枪地过。作为个搏击手,遇到这种情况,脑子必须比平时转得快,动作也得更狠、更准。我给你掰开了揉碎了说,保证不是那些干巴巴的教科书理论。第一步:预判与距离控制——这是生与死的关键首先,别傻站着让人家抡。你得.............
  • 回答
    大学里遇到的不公平,说实话,是每个过来人或多或少都经历过的事情。它不是轰轰烈烈的革命,更多时候是渗透在日常的点滴之中,像细小的沙子,磨得你心里不舒服。大家怎么面对?这问题问得好,因为答案不是单一的,而是五花八门,取决于每个人的性格、处境,以及对“公平”这件事的理解。一、 隐忍与自我调适:沉默的大多数.............

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有