我今天有一个面试。我有一个来自 哦的问题,关于 封装和 抽象的区别?
我回答我的知识,封装基本上是绑定数据成员和成员函数到一个单一的单位称为 同学们。而 抽象基本上是为了隐藏实现的复杂性并为用户提供方便的访问。我以为她不会介意我的回答。但她质疑,如果两者的目的都是为了隐藏信息,那么这两者之间的实际区别是什么呢?我不能给她任何答复。
在问这个问题之前,我阅读了 StackOverFlow 上关于这两个 哦概念之间区别的其他线程。但我发现自己没有能力说服面试官。
有人能举个最简单的例子来证明吗?
摘要: 通常是为了提供对一组类的多态访问。 一个抽象类不能被实例化,因此另一个类将不得不从它派生来创建一个更具体的表示。
抽象类的常见用法示例可以是模板方法设计模式的实现,其中引入了一个抽象注入点,以便具体类能够以自己的“具体”方式实现它。
见: 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 接口可以很好地实现这个概念。
接口提供各方之间的契约,例如,生产者和消费者。生产者生产产品而不让消费者知道产品是如何生产的。但是,通过界面,生产者让所有消费者知道什么产品可以购买。借助于抽象,生产者可以向他们的消费者推销产品。
封装:
封装是抽象的一个层次。同一个产品公司尝试屏蔽彼此生产组的信息。例如,如果一家公司生产葡萄酒和巧克力,封装有助于屏蔽信息,每个产品是如何从彼此。
藏了些东西,有点像药胶囊。我们不知道太空舱里有什么,我们只能拿走。和编程一样-我们只是隐藏一些特殊的方法或属性代码,它只提供输出,就像胶囊一样。简而言之,封装隐藏了数据。
摘要:
抽象意味着隐藏逻辑或实现。例如,我们服用药片,观察它们的颜色,但不知道它的作用是什么,以及它是如何与身体协同工作的。
这幅图很好地总结了两者之间的区别:
来源 给你
是的,抽象和封装是关于隐藏的,这是真的。
只使用相关的细节并在 设计水平中隐藏不必要的数据称为 抽象。(比如只为类‘ Car’选择相关属性,使其更加抽象或通用。)
封装 是将数据隐藏在 实施水平中。比如如何在直接/外部访问中实际隐藏数据。这是通过将数据和方法绑定到单个实体/单元来实现的,以防止外部访问。因此,封装也称为实现级的数据隐藏。
封装: 将代码和数据封装到一个单元中。Class是封装的一个例子,因为它包装了方法和属性。
Class
抽象: 隐藏内部细节并仅显示功能。抽象关注对象做什么,而不是它如何做。它提供了类的通用视图。
int number = 5; string aStringNumber = number.ToString();
在这里,ToString ()是抽象的,而这个机制 number变量如何转换成字符串并初始化成 aStringNumber是封装的。
number
aStringNumber
让我们以计算器为例。封装是内部电路,电池等,结合起来使它成为一个计算器。抽象就是不同的按钮如开关、透明等提供的按钮来操作它。
还有几点要说清楚,
我们不能混淆抽象化和抽象类,它们是不同的。
通常我们说抽象类或方法是基本上隐藏了一些东西。但是没有。.这是不对的。抽象是什么意思?谷歌搜索显示,英语单词抽象的意思是
存在于思想或观念中,但没有物质或具体的存在
对于抽象类也是如此。它没有隐藏方法的内容,但方法的内容已经是空的(没有物理或具体的存在) ,但它决定了一个方法应该如何(存在于思想中或作为一个想法)或一个方法应该在课堂上。
那么实际上什么时候使用抽象方法呢?
关于抽象类! 抽象类不能被实例化,只能被扩展! 但是为什么呢?
一个抽象类帮助我们避免创建它的新实例!
类中的抽象方法强制子类使用提供的签名实现该函数!
让我用上面讨论过的同一个例子来解释一下,请考虑同一台电视机。
封装 : 我们可以用遥控器进行的调整就是一个很好的例子-音量向上/向下,颜色和对比度-我们所能做的就是调整它的最小值和最大值,不能做任何超出在遥控器中提供的-想象一下 getter 和 setter 这里(setter 函数将检查提供的值是否有效,如果是,它处理操作,如果不允许我们进行更改-就像我们不能减少音量超过零,即使我们按下音量向下按钮100次)。
抽象 : 我们可以在这里举同样的例子,但是使用更高的度/上下文。音量下降按钮会减小音量——这是我们提供给用户的信息,用户既不知道遥控器里的红外发射器,也不知道电视里的接收器,以及随后解析信号的过程和电视里的微处理器架构。简单地说,它是不需要在上下文中-只是提供什么是必要的。在这里,我们可以很容易地将教科书定义联系起来,即隐藏内部实现,只提供它将做什么,而不是它如何做!
希望能澄清一点!
如果我是一个面对面试的人,我会说,作为最终用户的视角抽象和封装是相当相同的。这只不过是信息隐藏。从软件开发者的角度来看,抽象解决了设计层面的问题,封装解决了实现层面的问题
简而言之,Abstraction通过隐藏实现并实现一个接口以便能够与类的实例进行交互,从而发生在类级别。然而,Encapsulation用于隐藏信息; 例如,将成员变量设置为私有以禁止直接访问,并为它们提供 getter 和 setter 以进行间接访问。
Abstraction
Encapsulation
太好了! 如果我说 封装是一种高级的特定作用域抽象,
你们当中有多少人读了我的回答/对我的回答表示赞成。让我们深入探讨一下我为什么这么说。
在我提出索赔之前,我需要澄清两件事。
一个是数据隐藏,另一个是抽象
我说,“封装是一种高级的特定范围抽象”。为什么?因为我们可以把封装看作是数据隐藏 + 抽象
封装 = 数据隐藏 + 抽象
在封装中,我们需要隐藏数据,这样外部人员就看不到数据,我们需要提供可用于访问数据的方法。这些方法中可能有验证或其他特性,这些内容也隐藏在外部人员之中。这里,我们隐藏了访问方法的实现,它被称为抽象。
这就是为什么我说像上面这样的封装是一种抽象。
那么 不同在哪里?
不同之处在于,如果我们为了简单性、可维护性和安全性而向用户隐藏某些东西,那么抽象就是一个通用的抽象,
封装是与内部状态安全相关的一种特定的封装,我们在其中隐藏内部状态(数据隐藏) ,并提供访问数据的方法,而这些方法的实现也对外部人员隐藏(抽象)。
为什么我们需要抽象 当你做设计的时候,你不会谈论实现。你说,如果你给这个方法这些参数,它会给出这些输出。 我们隐藏了该方法的内部实现,并讨论了它将做什么,因此这是一个抽象。
例子
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 > 房间的上下文中
因此,抽象更多地与类相关,而 封装更多地与类的内部对象、属性和方法相关。
封装
简单地说,封装是数据隐藏(信息隐藏) ,而 抽象是细节隐藏(实现隐藏)
封装 是意义的组合。
抽象是意义的简化。