封装与抽象的区别

我今天有一个面试。我有一个来自 的问题,关于 封装抽象的区别?

我回答我的知识,封装基本上是绑定数据成员和成员函数到一个单一的单位称为 同学们。而 抽象基本上是为了隐藏实现的复杂性并为用户提供方便的访问。我以为她不会介意我的回答。但她质疑,如果两者的目的都是为了隐藏信息,那么这两者之间的实际区别是什么呢?我不能给她任何答复。

在问这个问题之前,我阅读了 StackOverFlow 上关于这两个 概念之间区别的其他线程。但我发现自己没有能力说服面试官。

有人能举个最简单的例子来证明吗?

184303 次浏览

摘要: 通常是为了提供对一组类的多态访问。 一个抽象类不能被实例化,因此另一个类将不得不从它派生来创建一个更具体的表示。

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

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

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

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

封装 隐藏了变量或某些实现,这些变量或实现可能会经常更改 在课堂上,以防止外部人员直接访问它。他们必须通过 getter 和 setter 方法访问它。

抽象 也用于隐藏某些内容,但是在 高学位(类,接口)中。使用抽象类(或接口)的客户机不关心它是什么,他们只需要知道它能做什么。

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

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

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

两者的区别仅仅是 观点
封装字是用来隐藏数据,如果我们的目的是防止客户端看到我们的逻辑内视图

抽象词是用来隐藏数据,如果我们的目的是显示我们的客户端外部视图

外面的景色意味着让我们假设

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

在这里,我们使用交换在冒泡排序,只是为了显示我们的客户端什么逻辑,我们正在应用,如果我们替换掉交换(x,y)与整个代码在这里,在一个单一的实例中,他/她不能理解我们的逻辑

抽象: 应该公开给类外部的最小函数和变量是什么。

封装: 如何实现这个需求,意味着如何实现它。

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

这篇文章的结论如下:

抽象、信息隐藏和封装是非常不同的, 但是高度相关的概念。有人可能会说抽象是一种 技术,帮助我们确定哪些特定的信息应该是 可见,以及应该隐藏哪些信息。然后进行封装 以隐藏的方式包装信息的技术 什么应该被隐藏,并使可见什么是打算 看得见。

抽象

在 Java 中,抽象意味着将信息隐藏到现实世界中。它建立了当事人之间的合同,告诉“我们应该做什么来使用服务”。

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

接口提供各方之间的契约,例如,生产者和消费者。生产者生产产品而不让消费者知道产品是如何生产的。但是,通过界面,生产者让所有消费者知道什么产品可以购买。借助于抽象,生产者可以向他们的消费者推销产品。

封装:

封装是抽象的一个层次。同一个产品公司尝试屏蔽彼此生产组的信息。例如,如果一家公司生产葡萄酒和巧克力,封装有助于屏蔽信息,每个产品是如何从彼此。

  1. 如果我有一个单独的包,一个用于葡萄酒,另一个用于巧克力,如果所有的类都声明在包中作为默认的访问修饰符,我们给所有类的包级别封装。
  2. 在包中,如果我们将每个类归档(成员字段)声明为 私有的,并且有一个公共方法来访问这些字段 给这些字段提供类级别封装

封装:

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

摘要:

抽象意味着隐藏逻辑或实现。例如,我们服用药片,观察它们的颜色,但不知道它的作用是什么,以及它是如何与身体协同工作的。

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

enter image description here

来源 给你

是的,抽象和封装是关于隐藏的,这是真的。

  • 只使用相关的细节并在 设计水平中隐藏不必要的数据称为 抽象。(比如只为类‘ Car’选择相关属性,使其更加抽象或通用。)

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

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

抽象: 隐藏内部细节并仅显示功能。抽象关注对象做什么,而不是它如何做。它提供了类的通用视图。

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

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

让我们以计算器为例。封装是内部电路,电池等,结合起来使它成为一个计算器。抽象就是不同的按钮如开关、透明等提供的按钮来操作它。

还有几点要说清楚,

我们不能混淆抽象化和抽象类,它们是不同的。

通常我们说抽象类或方法是基本上隐藏了一些东西。但是没有。.这是不对的。抽象是什么意思?谷歌搜索显示,英语单词抽象的意思是

存在于思想或观念中,但没有物质或具体的存在

对于抽象类也是如此。它没有隐藏方法的内容,但方法的内容已经是空的(没有物理或具体的存在) ,但它决定了一个方法应该如何(存在于思想中或作为一个想法)或一个方法应该在课堂上。

那么实际上什么时候使用抽象方法呢?

  • 当基类中的方法在扩展它的每个子类中都有所不同时。
  • 因此,您需要确保子类实现了这个函数。
  • 这也确保了方法具有强制签名,如,它必须具有 n 个参数。

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

  • 必须防止使用抽象方法的类创建自己的实例,因为其中的抽象方法没有任何有意义的实现。
  • 你甚至可以使一个类变得抽象,如果由于某种原因你发现拥有一个类的实例意义不大。

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

类中的抽象方法强制子类使用提供的签名实现该函数!

让我用上面讨论过的同一个例子来解释一下,请考虑同一台电视机。

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

抽象 : 我们可以在这里举同样的例子,但是使用更高的度/上下文。音量下降按钮会减小音量——这是我们提供给用户的信息,用户既不知道遥控器里的红外发射器,也不知道电视里的接收器,以及随后解析信号的过程和电视里的微处理器架构。简单地说,它是不需要在上下文中-只是提供什么是必要的。在这里,我们可以很容易地将教科书定义联系起来,即隐藏内部实现,只提供它将做什么,而不是它如何做!

希望能澄清一点!

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

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

太好了! 如果我说 封装是一种高级的特定作用域抽象,

你们当中有多少人读了我的回答/对我的回答表示赞成。让我们深入探讨一下我为什么这么说。

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

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

数据隐藏

大多数情况下,我们不会直接访问我们的内部数据。我们的内部数据不应该直接外泄,因为外人无法直接访问我们的内部数据。这都与安全性有关,因为我们需要保护特定对象的内部状态。


抽象

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


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

封装 = 数据隐藏 + 抽象

在封装中,我们需要隐藏数据,这样外部人员就看不到数据,我们需要提供可用于访问数据的方法。这些方法中可能有验证或其他特性,这些内容也隐藏在外部人员之中。这里,我们隐藏了访问方法的实现,它被称为抽象。

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

那么 不同在哪里?

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

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

为什么我们需要抽象 当你做设计的时候,你不会谈论实现。你说,如果你给这个方法这些参数,它会给出这些输出。 我们隐藏了该方法的内部实现,并讨论了它将做什么,因此这是一个抽象。

例子

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;
}


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

基本上,

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

一个非常实际的例子是。

这么说吧,我想加密我的密码。

  • 我不想知道细节,我只是打电话 Crypt (password) ,它返回一个加密的 密码。

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

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

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

    那么这些加密类有自己的实现方式 保护其实现不受外界干扰的加密技术

    这被称为 封装。隐藏它应该如何做。

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

隐藏并发症与保护实现

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

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

以下面的堆栈类为例:

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

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

抽象有助于在堆栈上进行推或弹出操作,而不必担心要推或弹出的步骤是什么

抽象 顾名思义,抽象的意思是 摘要简短关于某事物的意思。在面向对象的抽象类的情况下,这些类并不包含现实世界中关于这个对象的所有信息,例如,你想预订一个酒店房间,如果你的对象是你主要关心的 房间:

  • 价格、大小、床位等。

但你不在乎

  • 他们在旅馆房间里用来供电的电线。
  • 他们用哪种水泥来建造它

所以,你得到关于 房间抽象信息,这是你所关心的。

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

现在,人们可以说 抽象在这里也适用:

你可以说 开关的内部连接也是抽象的,所以这一定是 抽象的情况,但这里有一些细微的差别:

抽象 更多的是一个上下文的东西,它没有非抽象的信息,比如你不关心的线路信息,不存在于预订酒店 房间的网站上下文中(就像你的类 房间没有关于它的线路网格的信息,因为这个 房间只是委托给在线预订) ,而 封装是更细粒度的,它意味着隐藏和封装你不需要关心的细粒度的东西,在 开关上切换灯泡隐藏在交换机内的线路(像类的私有属性/方法)。 现在,开关类拥有这些信息,但是对您来说是隐藏的。另一方面,房间类没有关于酒店房间布线设计的信息,因为它甚至不在在线预订 < em > 房间的上下文中

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

抽象

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

封装

  • 是将数据和功能封装到一个单元中的过程
  • 其目的是通过防止直接访问和只提供一种更安全和间接的方式来保护数据

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

封装 是意义的组合。

抽象是意义的简化。