隐藏实现细节是封装还是抽象?

3

有些人将抽象定义为:

通过提供基本功能上的一层,隐藏实现细节。

从对象的用户隐藏实现细节不是封装的一部分吗?

假设 Animal 类有一个 eat() 函数,那么向对象的用户提供此接口是封装还是抽象?或者提供函数名称以供使用是抽象,而隐藏方法实现部分是封装。

我真的很困惑,在许多地方都是抽象,而许多人说实现细节隐藏是封装?

在这个SO问题的顶部答案中:

抽象=对象外部;封装(通过信息隐藏实现)=对象内部。

这是否意味着对象接口曝光是抽象,而对象内部的数据隐藏是封装?

2个回答

5

隐藏实现细节是封装还是抽象?

抽象化是关于提供一个附加层,其中包含接口和抽象类。这一层(接口和抽象类)告诉我们需要做什么,但不告诉我们如何做。因此,隐藏实现被称为抽象化。

理解抽象概念的最好例子是所有J2EE/JMS规范都提供抽象(通常是接口)给应用程序供应商,然后这些接口将由不同的供应商(如Tomcat/JBoss/Weblogic/IBM等)实现规范的实际定义/行为(称为实现)。

抽象只谈论需要做什么, 实现告诉我们如何做。

抽象提供了在运行时注入行为的能力(即多态性)。现在以Spring框架(或实际上任何DI框架,如Guice等)为例,Spring DI容器注入提供的bean(通过xml或注释)实现对象(实现)在运行时注入到给定的接口类型(抽象)中。

这是否意味着对象接口的展示是抽象,对象内部的数据隐藏是封装?
是的,在Java中,可以使用接口或有时使用抽象类(如J2EE HttpServlet等)来实现抽象。
现在谈到封装,它主要关注于为类/方法/字段提供/定义正确级别的访问权限(隐藏/保护类和类成员)。在Java中,可以使用访问修饰符(protected/private/public等)来实现封装。
您可以在 这里 了解更多关于Java中抽象的信息,以及在 这里 了解更多有关重写(实现)和隐藏方法的信息。

请参见以下与抽象和封装有关的编程内容的答案1和2:https://dev59.com/l3RB5IYBdhLWcg3wCjcV - cruxion effux
谢谢回答。请注意,我知道如何在Java中完成,但是在上面的问题的顶部答案中,他们明确提到将实现隐藏为封装。同样,在这个问题的顶部答案中也很清楚:https://dev59.com/MGQn5IYBdhLWcg3wTloS 还有这个问题的顶部答案:https://dev59.com/X2ct5IYBdhLWcg3wedOP - cruxion effux
我在链接中看到了你所提到的内容。 - developer
问题在于,您可以将事物放置在不同的短语中,"封装是隐藏实现方式" 的含义是封装是关于提供正确级别的访问(保护类成员,成员包含方法和方法包含实现)。 - developer

3
作为编程中的许多事物一样,这两个术语都没有明确定义,都可能会修订,并且不一定是互斥的。我知道这可能令人不满意,但我会抵制对这些术语进行纯技术定义。
抽象在Wikipedia上有一个相当好的定义。它是提取某物的“本质”,隐藏不必要的所有内容。没错,在Java中,“抽象”方法或“抽象”类(接口)存在,并且可以用于提供概念上的抽象,但仅使用接口并不自动符合我的“抽象”标准。这只是实现它的技术工具。另一方面,也可以通过非抽象方法来抽象概念。
封装是一个相关的概念,不完全相同,但也不是完全独立的。维基百科 的定义很不好,因为它侧重于语言。封装的概念意味着保护单元/方法/类/模块等内部的详细信息。它对对象的“内部”和“外部”都是相关的。如果您需要修改多个“层”(如持久化、业务、GUI、API等)上的某个业务对象的新“字段”,则说明您没有封装。我倾向于同意您引用的 Booch 引用语,但问题在于人们对“对象的本质特征”有很大的误解。例如,封装永远不会允许直接访问对象的内部字段。这意味着 getter(尤其是 setter)是不允许的。当然,可以争论“封装程度”的问题,但我至少看到的大多数业务代码都无法很好地实现封装。

Edward Berard将抽象定义为“选择”技术(应该使哪些信息可见/隐藏),并将封装定义为“呈现”技术(应该如何使信息可见/隐藏)。 - Géry Ogam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接