130

我今天接受了采访。我有一个来自OOP的问题,关于封装抽象之间的区别?

我回答她说,封装基本上是将数据成员和成员函数绑定到一个名为Class的单元中。而抽象基本上是为了隐藏实现的复杂性并为用户提供方便的访问。我以为她会接受我的回答。但她质疑,如果两者的目的都是为了隐藏信息,那么这两者之间的实际区别是什么?我无法给她任何答案。

在问这个问题之前,我阅读了 StackOverFlow 上的其他线程,了解这两个OOP概念之间的区别。但我发现自己无法说服面试官。

任何人都可以用一个最简单的例子来证明它的合理性吗?

4

21 回答 21

114

封装隐藏了类中可能经常更改的变量或某些实现,以防止外人直接访问它。他们必须通过 getter 和 setter 方法访问它。

抽象也用于隐藏某些东西,但程度更高(类,接口)。使用抽象类(或接口)的客户并不关心它是什么,他们只需要知道它可以做什么。

于 2013-03-02T16:03:40.383 回答
35

这张图片很好地总结了两者之间的区别:

在此处输入图像描述

来源在这里

于 2018-07-12T11:20:19.683 回答
26

封装:将代码和数据一起包装成一个单元。Class是封装的一个例子,因为它包装了方法和属性。

抽象:隐藏内部细节并仅显示功能。抽象关注对象的作用而不是它的作用。它提供类的通用视图。

int number = 5;
string aStringNumber = number.ToString(); 

在这里, ToString() 是抽象的。而这个机制number变量如何转换为字符串并初始化为aStringNumber封装。

让我们以一个真实世界的计算器为例。封装是内部电路、电池等,它们结合起来使它成为一个计算器。抽象是提供用于操作它的不同按钮,如开关、清除和其他按钮。

于 2018-12-22T04:17:17.580 回答
15

抽象 - 是识别一组对象的共同基本特征的过程(和此过程的结果)。有人可能会说抽象是泛化的过程:所有考虑的对象都包含在对象的超集中,所有这些对象都具有给定的属性(但在其他方面有所不同)。

封装——是将数据和操作这些数据的函数封装到一个单元中的过程,以便对外界隐藏内部实现。

这是与特定编程语言无关的一般答案(就像问题一样)。所以答案是:抽象和封装没有任何共同之处。但是它们的实现可能彼此相关(例如,在 Java 中:封装 - 细节隐藏在类中,抽象 - 细节根本不存在于类或接口中)。

于 2013-06-20T20:19:48.833 回答
9

是的 !!!!如果我说封装是一种高级的特定范围抽象

你们中有多少人阅读/赞成我的回答。让我们深入了解我为什么这么说。

在我提出索赔之前,我需要澄清两件事。

一个是数据隐藏,另一个是抽象

数据隐藏

大多数时候,我们不会直接访问我们的内部数据。我们的内部数据不应该直接出去,因为外部人员无法直接访问我们的内部数据。这一切都与安全有关,因为我们需要保护特定对象的内部状态。


抽象

为简单起见,隐藏内部实现称为抽象。在抽象中,我们只关注必要的事情。基本上,我们抽象地谈论“做什么”而不是“如何做”。安全性也可以通过抽象来实现,因为我们不会强调“我们是如何实现的”。由于我们可以更改实现,因此可维护性将会提高,但不会影响我们的最终用户。


我说过,“封装是一种高级的特定范围抽象”。为什么?因为我们可以将封装视为数据隐藏+抽象

封装 = 数据隐藏 + 抽象

在封装中,我们需要将数据隐藏起来,让外部的人看不到数据,我们需要提供可以用来访问数据的方法。这些方法可能在这些东西中具有验证或其他功能,这些东西也对外部人员隐藏。所以在这里,我们隐藏了访问方法的实现,它被称为抽象。

这就是为什么我像上面所说的封装是一种抽象。

那么区别在哪里

不同之处在于,如果我们为了简单性、可维护性和安全性而对用户隐藏某些东西,那么抽象是通用的,并且,

封装是一种与内部状态安全相关的特定封装,其中我们隐藏了内部状态(数据隐藏),我们提供了访问数据的方法,并且这些方法的实现也对外部人员隐藏(抽象)。

为什么我们需要抽象 当您进行设计时,您不会谈论实现。你说如果你给这个方法提供这些参数,它会给出这些输出。我们隐藏方法的内部实现并讨论它将做什么,所以这是一个抽象。

例子

public int add(int a, int b);

这个方法定义告诉我们,如果你给两个变量,它会做加法并返回结果。

在这里,我们不会看实现,我们只看这个方法做了什么,而不是它是怎么做的。方法实现可能因开发人员而异。1.

public int add(int a, int b){
   return a + b; 
}
public int add(int a, int b){

   return b + a; 
}

两种方法在做同样的事情,但它们的实现不同。

基本上,

需要抽象来对系统建模。需要封装以增强系统安全性。

于 2021-01-02T19:46:21.907 回答
8

抽象: 通常用于提供对一组类的多态访问。一个抽象类不能被实例化,因此另一个类必须从它派生来创建一个更具体的表示。

抽象类的常见用法示例可以是模板方法设计模式的实现,其中引入了抽象注入点,以便具体类可以以自己的“具体”方式实现它。

见:http://en.wikipedia.org/wiki/Abstraction_(computer_science)

封装: 这是向将要使用它的客户端隐藏特定类的实现复杂性的过程,请记住,“客户端”可能是编写该类的人的程序或事件。

参见:http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)

于 2013-03-02T16:00:07.647 回答
7

有一篇很棒的文章深入探讨了抽象、封装和信息隐藏之间的区别:http ://www.tonymarston.co.uk/php-mysql/abstraction.txt

以下是文章的结论:

抽象、信息隐藏和封装是非常不同但高度相关的概念。有人可能会争辩说,抽象是一种帮助我们识别哪些特定信息应该可见,哪些信息应该隐藏的技术。封装是一种封装信息的技术,以隐藏应该隐藏的内容,并让原本应该可见的内容变得可见。

于 2018-01-26T03:37:44.387 回答
4

封装:

隐藏的东西,有点像药丸。我们不知道胶囊里有什么,我们只是把它拿走。和编程一样——我们只是隐藏了一些特殊的方法或属性代码,它只给出输出,和胶囊一样。简而言之,封装隐藏了数据。

抽象:

抽象意味着隐藏逻辑或实现。例如,我们服用药片并查看它们的颜色,但不知道这样做的目的是什么以及它如何作用于身体。

于 2018-03-19T05:38:58.507 回答
4

是的,抽象和封装确实是关于隐藏。

  • 仅使用相关细节并在设计级别隐藏不必要的数据称为抽象。(就像只为“汽车”类选择相关属性以使其更抽象或更通用。)

  • 封装是在实现级别隐藏数据。就像如何实际隐藏数据以防止直接/外部访问一样。这是通过将数据和方法绑定到单个实体/单元来完成的,以防止外部访问。因此,封装也称为实现级别的数据隐藏。

于 2018-08-12T01:24:30.620 回答
3

一个非常实际的例子是。

假设我想加密我的密码。

  • 我不想知道细节,我只是调用 encryptionImpl.encrypt(password) 它返回一个加密的密码。

    public interface Encryption{ public String encrypt(String password); }

    这称为抽象。它只是显示应该做什么。

  • 现在让我们假设我们有两种类型的加密 Md5 和 RSA,它们从第三方加密 jar 实现加密。

    然后那些 Encryption 类有自己的实现加密的方式来保护它们的实现不受外界的影响

    这称为封装。隐藏应该如何完成。

记住:应该做什么和应该怎么做。

隐藏复杂性与保护实现

于 2021-01-13T18:13:57.483 回答
2

两者的区别只是View Point
Encapsulation 字用于隐藏数据,如果我们的目标是防止客户看到我们逻辑的内部视图

如果我们的目标是向客户展示外部视图,则抽象词用于隐藏数据

外部视图意味着让假设

BubbleSort(){
//code 
swap(x,y);
}

在这里我们使用冒泡排序中的交换来向我们的客户展示我们正在应用什么逻辑,如果我们在这里用整个代码替换交换(x,y),在单个实例中他/她无法理解我们的逻辑

于 2014-02-25T09:40:59.913 回答
2

让我用上面讨论的相同例子来解释它。请考虑同一台电视。

封装:我们可以使用遥控器进行的调整就是一个很好的例子 - 音量增大/减小、颜色和对比度 - 我们所能做的就是将其调整到提供的最小值和最大值,并且不能做任何超出遥控器提供的东西 -想象一下这里的 getter 和 setter(setter 函数将检查提供的值是否有效,如果是,它会处理操作,如果不是,则不允许我们进行更改 - 就像我们不能将音量降低到零以上,即使我们按下音量按钮一百次)。

抽象:我们可以在这里采用相同的示例,但具有更高的程度/上下文。降低音量按钮将降低音量 - 这是我们提供给用户的信息,用户不知道遥控器内部的红外发射器和电视中的接收器以及解析信号和微处理器的后续过程电视里面的建筑。简而言之,在上下文中不需要它 - 只需提供必要的内容。在这里可以很容易地关联教科书的定义,即隐藏内部实现并只提供它将做什么而不是如何做到这一点!

希望它澄清一点!

于 2020-06-08T16:42:24.207 回答
2

简而言之,Abstraction通过隐藏实现和实现接口以能够与类的实例进行交互,发生在类级别。鉴于,Encapsulation用于隐藏信息;例如,将成员变量设为私有以禁止直接访问,并为它们提供 getter 和 setter 以进行间接访问。

于 2020-10-30T13:28:17.460 回答
1

抽象 顾名思义,抽象意味着对某事的总结简要说明。在 OOP 的情况下,抽象类是那些不包含现实世界中该对象的所有信息的类,例如。您想预订酒店房间,如果您的对象是您主要关心的房间:

  • 它的价格、大小、床位等。

但你不在乎

  • 他们在酒店房间里用过的电线。
  • 他们用什么水泥建造的

因此,您可以获得有关您关心的房间的抽象信息。

另一方面,封装基本上是将相关信息封装在一起,例如。您预订了酒店房间,您去那里按开关打开灯泡。现在开关对象具有打开灯泡所需的所有内部接线,但您真的不关心这些接线。您只关心灯泡是否打开。

现在可以说抽象也适用于这里:

可以说交换机的内部布线对您来说也是抽象的,所以这一定是抽象的情况,但这里有一些细微的区别:

抽象更多是一个上下文的东西,它没有非抽象的信息,比如你不关心的布线信息,不存在于预订酒店房间的网站的上下文中(比如你的教室没有关于它的布线网格,因为这个房间只被委托用于在线预订),而封装更细化,它意味着隐藏和封装你不需要关心的细颗粒物,用于打开灯泡开关隐藏布线在交换机内部(如类的私有属性/方法)。现在switch类有信息,但它对你是隐藏的。另一方面room class 没有关于酒店房间布线设计的信息,因为它甚至没有在房间在线预订的上下文中

因此,抽象更多地与类相关,而封装更多地与类对象、属性和方法的内部相关。

于 2021-08-01T12:22:53.373 回答
1

抽象

  • 是隐藏如何,只显示什么的过程
  • 目的是简化信息并向用户隐藏不必要的细节

封装

  • 是将数据和功能包装到一个单元中的过程
  • 目的是通过防止直接访问并仅提供更安全和间接的方式来保护数据
于 2021-11-09T10:19:17.333 回答
0

抽象

在 Java 中,抽象意味着将信息隐藏到现实世界中。它建立了双方之间的合同,以告知“我们应该如何使用服务”。

例如,在 API 开发中,只向世界展示了服务的抽象信息,而不是实际的实现。java中的接口可以很好地帮助实现这个概念。

接口提供各方之间的合同,例如,生产者和消费者。生产者在不让消费者知道产品是如何制造的情况下生产商品。但是,通过界面,Producer 让所有消费者知道可以购买什么产品。在抽象的帮助下,生产者可以将产品推销给他们的消费者。

封装:

封装是抽象的一层。同一产品公司尝试屏蔽来自其他生产组的信息。例如,如果一家公司生产葡萄酒和巧克力,封装有助于屏蔽每种产品如何相互制造的信息。

  1. 如果我有一个单独的包,一个用于葡萄酒,另一个用于巧克力,并且如果所有类都在包中声明为默认访问修饰符,那么我们将为所有类提供包级封装。
  2. 在一个包中,如果我们将每个类字段(成员字段)声明为私有并具有访问这些字段的公共方法,这样就可以对这些字段进行类级别的封装
于 2018-02-22T12:15:46.347 回答
0

如果我是面对面试的人,我会说最终用户的视角抽象和封装是相当的。这不过是信息隐藏。从软件开发人员的角度来看,抽象解决了设计级别的问题,封装解决了实现级别的问题

于 2020-10-19T18:02:07.497 回答
0

封装是将数据和方法封装在一个单元中,使数据只能通过方法(getter/setter)访问,以确保数据的安全性。

抽象隐藏了工作如何完成的内部实现细节。

以以下堆栈类为例:

Class Stack
{
private top;
void push();
int pop();
}

现在封装有助于保护内部数据,因为无法直接在外部访问顶部。

抽象有助于在堆栈上进行推送或弹出,而无需担心推送或弹出的步骤是什么

于 2021-02-21T16:50:01.177 回答
0

简单来说,封装就是数据隐藏(信息隐藏),抽象就是细节隐藏(实现隐藏)

于 2022-03-02T07:28:48.200 回答
-1

再多说几句就明白了

绝不能混淆数据抽象和抽象类。它们是不同的。

通常我们说抽象类或方法基本上是为了隐藏一些东西。但是没有..那是错误的。抽象这个词是什么意思?谷歌搜索说英文单词abstraction是什么意思

“存在于思想中或作为一个想法,但没有物理或具体的存在。”

在抽象类的情况下也是如此。它不是隐藏方法的内容,而是方法的内容已经是空的(没有物理或具体的存在),但它决定了方法应该如何(存在于思想中或作为一种想法)或方法应该如何在课程中.

那么你什么时候真正使用抽象方法呢?

  • 当基类中的方法在扩展它的每个子类中都不同时。
  • 所以你要确保子类实现了这个功能。
  • 这也确保了具有强制签名的方法必须具有 n 个参数。

所以关于抽象类!- 抽象类不能被实例化,只能扩展!但为什么 ?

  • 必须防止具有抽象方法的类创建自己的实例,因为其中的抽象方法没有任何有意义的实现。
  • 如果由于某种原因您发现拥有该类的实例意义不大,您甚至可以将类抽象化。

抽象类帮助我们避免创建它的新实例!

类中的抽象方法强制子类使用提供的签名确保实现该功能!

于 2019-04-04T07:34:07.177 回答
-4

抽象:应该向我们的类外部公开的最少函数和变量是什么。

封装:如何实现这个需求,意思是如何实现。

于 2016-12-07T12:57:17.373 回答