【问题标题】:Difference between Encapsulation and Abstraction封装与抽象的区别
【发布时间】:2013-02-17 01:17:03
【问题描述】:

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

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

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

谁能用一个最简单的例子来证明它的合理性?

【问题讨论】:

标签: oop encapsulation abstraction


【解决方案1】:

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

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

【讨论】:

  • 完美。在我看来,您的回答只是针对我的面试官问题。我试图用一个实际的例子来重申你的回复。请让我知道,如果它证明你的答复是合理的。让我们以电视为例。封装是内部电路、LED 等结合起来使其成为电视。抽象是提供给它操作的开关、声音、通道设置等按钮。
  • 家伙抽象与隐藏实现无关......抽象是一种与类进行多态交互的方法
  • @Mortalus - 我不同意你的第一句话“抽象与隐藏实现无关”。我认为,当我们开始学习抽象概念时,我们学到的第一件事就是隐藏实现的复杂性并为用户提供一些接口来使用它。因为用户可能对实现复杂性不感兴趣。你可以举一个电视或交流电的实际例子。另一件事是,如果它不隐藏实现,那么为什么我们在抽象类中提供一个没有主体的方法。我们显然在这里隐藏了实现。
  • @Mortalus - 另外,您提到了一个 wiki 链接。这是第一个声明 - “在计算机科学中,抽象是使用与其含义(语义)相似的表示形式定义数据和程序的过程,同时隐藏实现细节。抽象试图减少和分解细节,以便程序员一次可以专注于几个概念。”本身表明抽象旨在隐藏实现。我同意你的第二个陈述,但不同意第一个。
  • 我认为封装更多的是构建单个单元,与您隐藏与否无关。抽象更多的是隐藏事物,如果我错了,请纠正。
【解决方案2】:

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

来源here

【讨论】:

    【解决方案3】:

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

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

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

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

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

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        【解决方案5】:

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

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

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

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

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

        【讨论】:

        • 抽象和抽象类有关吗??
        • @vishnuviswanath,是的,我们可以使用抽象类和接口来实现抽象。
        【解决方案6】:

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

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

        在申请之前我需要澄清两件事。

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

        数据隐藏

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


        抽象

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


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

        封装=数据隐藏+抽象

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

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

        那么区别在哪里?

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

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

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

        例子

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

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

        基本上,

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

        【讨论】:

        • 这可能是一个很好的解释,但我猜它仍然不能回答问题。实际的问题是,如果两者都是关于隐藏数据(正如您所说,一个是另一个的专业化),那么为什么它们是 OOPS 中的独立概念?如果一个人是百万富翁和亿万富翁,那么我们通常会省略百万富翁部分。得到它? (教科书将抽象、封装、继承和多态列为 OOP 的 4 个概念)
        • @MidhunrajRPillai,我用抽象的使用位置更新了答案
        • @RCvaram 我喜欢你回答的最后一行
        【解决方案7】:

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

        这是文章的结论:

        抽象、信息隐藏、封装是很不一样的, 但高度相关的概念。有人可能会说抽象是一种 帮助我们识别哪些特定信息应该是的技术 可见,哪些信息应该隐藏。然后封装 以隐藏的方式包装信息的技术 什么应该隐藏,什么应该是可见的 可见。

        【讨论】:

          【解决方案8】:

          封装:

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

          抽象:

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

          【讨论】:

            【解决方案9】:

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

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

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

            【讨论】:

            • 您能解释一下这个答案与其他 12 个现有答案有何不同吗?
            【解决方案10】:

            一个非常实际的例子是。

            假设我想加密我的密码。

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

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

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

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

              然后那些加密类有自己的实现方式 加密,保护他们的实施免受外人的影响

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

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

            隐藏复杂性与保护实现

            【讨论】:

              【解决方案11】:

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

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

              外观意味着假设

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

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

              【讨论】:

                【解决方案12】:

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

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

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

                希望它澄清一点!

                【讨论】:

                  【解决方案13】:

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

                  【讨论】:

                    【解决方案14】:

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

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

                    但你不在乎

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

                    因此,您将获得关于您关心的房间抽象信息。

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

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

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

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

                    在线预订的上下文中

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

                    【讨论】:

                      【解决方案15】:

                      抽象

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

                      封装

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

                      【讨论】:

                        【解决方案16】:

                        抽象

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

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

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

                        封装:

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

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

                        【讨论】:

                          【解决方案17】:

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

                          【讨论】:

                          • 你能详细说明答案吗?
                          【解决方案18】:

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

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

                          以下列堆栈类为例:

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

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

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

                          【讨论】:

                            【解决方案19】:

                            再多说几句就明白了,

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

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

                            “存在于思想或观念中,但没有物理或具体的存在。”

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

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

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

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

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

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

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

                            【讨论】:

                            • 问题是关于抽象与封装,而不是抽象类!
                            【解决方案20】:

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

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

                            【讨论】:

                            • 封装不是实现抽象的手段。它们是 2 个略有不同的概念,但有着微妙的联系。
                            • 我认为两者不是不同的概念,因为你可以用抽象类实现封装。
                            猜你喜欢
                            • 2014-09-21
                            • 2012-02-16
                            • 1970-01-01
                            • 1970-01-01
                            • 2017-11-29
                            • 1970-01-01
                            • 1970-01-01
                            • 2012-05-24
                            • 2017-11-01
                            相关资源
                            最近更新 更多