封装与抽象?

问题描述 投票:127回答:13

以下是封装和抽象的简要定义。

抽象:

Java中的抽象过程用于隐藏某些细节,仅显示对象的基本特征。换句话说,它处理对象(界面)的外部视图。我在不同站点看到的唯一好例子是界面。

封装:

它基本上是在私有,公共,受保护等修饰符的帮助下隐藏对象的状态。我们只在需要时通过公共方法暴露状态。

我们用privatepublic这样的修饰语所取得的成就也隐藏了来自外面世界的不必要的细节,这些细节只不过是一个抽象的概念

因此,从上面的解释来看,封装是抽象的一部分,或者我们可以说它是抽象的一个子集。但是,为什么封装术语是在我们只能用抽象来处理的时候发明的呢?我确信应该有一些区别于它们的主要区别,但网上的大多数材料对两者都说几乎相同。

虽然这个问题早已在这个论坛上提出过,但我再次发布它并带有特别的怀疑。一些回复还说抽象是一个概念,封装是实现。但我不买这个 - 如果是真的,那么我可以认为提供这两个不同的概念来迷惑我们。

更新: - 5年后,我提出了自己的答案,这是基于这篇文章及以下答案的要点

  1. difference between abstraction and encapsulation?
  2. encapsulation vs abstraction real world example
java oop
13个回答
95
投票

封装是一种用作抽象的一部分的策略。封装是指对象的状态 - 对象封装其状态并将其隐藏在外部;类的外部用户通过其方法与之交互,但无法直接访问类状态。因此,该类抽象出与其状态相关的实现细节。

抽象是一个更通用的术语,它也可以通过(其中)子类化来实现。例如,标准库中的接口List是一系列项目的抽象,由它们的位置索引,List的具体示例是ArrayListLinkedList。与List交互的代码在其正在使用的列表的详细信息上进行抽象。

如果没有通过封装隐藏底层状态,通常是不可能的 - 如果一个类暴露其内部状态,它不能改变其内部工作,因此不能被抽象。


1
投票

注意:我正在分享这个。这并不意味着这不是一个好的答案,而是因为我很容易理解。

回答:

当一个类被概念化时,在给定上下文的情况下我们可以拥有哪些属性。如果我们在动物园的背景下设计动物类,重要的是我们有一个属性作为animalType来描述国内或野生动物。当我们在不同的上下文中设计类时,此属性可能没有意义。

同样,我们在课堂上会有什么样的行为?抽象也在这里应用。有什么是必要的,这将是什么过量?然后我们从班级中删除了一些信息。这个过程正在应用抽象。

当我们要求封装和抽象之间存在差异时,我会说,encapsulation使用抽象作为一个概念。那么,它只是封装。不,抽象甚至是作为继承和多态的一部分应用的概念。

Go在这里有关于这个主题的更多解释。


1
投票

让我们尝试以不同的方式理解。

如果没有抽象可能会发生什么,如果封装不存在会发生什么。

如果不存在抽象,则可以说对象使用较少。您无法识别对象,也无法访问它的任何功能。举一个电视的例子,如果你没有选择开机,改变频道,增加或减少音量等,那么电视的用途是什么,你如何使用它?

如果Encapsulation不存在或没有正确实现,那么您可能会滥用该对象。数据/组件可能会被误用。以电视的相同例子为例,如果没有对电视音量进行封装,那么音量控制器可能会因为低于或超出其限制(0-40 / 50)而被误用。


1
投票

封装保护以折叠对象/实例与外部实体的内部行为。因此,应该提供一个控件来确认所提供的数据不会损害实例/对象的内部系统以使其存在。

很好的例子,Divider是一个具有两个实例变量dividend和divisor以及一个方法getDividedValue的类。

你能想到,如果除数设置为0,那么内部系统/行为(getDivided)将会中断。

因此,可以通过方法抛出异常来保护对象内部行为。


0
投票

在一个简单的句子中,我可以说:抽象的本质是提取基本属性,同时省略不必要的细节。但为什么我们要省略不必要的细节呢?关键的动力是防止变革的风险。您可能会认为抽象与封装相同。但封装意味着将一个或多个项目封装在容器中,而不是隐藏细节。如果您认为“封装的所有内容也都被隐藏了”。这显然不是真的。例如,即使信息可以封装在记录结构和数组中,通常也不会隐藏此信息(除非通过其他机制隐藏)。


114
投票

抽象是用简单的术语描述某些东西的概念,即抽象出细节,以便专注于重要的东西(这也可以在抽象艺术中看到,例如,艺术家专注于图像的构建块,例如颜色或形状)。同样的想法通过使用继承层次结构转换为OOP,其中更抽象的概念位于顶层,更底层的更具体的概念建立在它们的抽象之上。在最抽象的层面上,根本没有实现细节,也许很少有共性,随着抽象的减少而增加。

举个例子,顶部可能是一个带有单个方法的接口,然后是下一个层次,提供了几个抽象类,可能会也可能不会填充有关顶层的一些细节,但是通过添加自己的抽象方法来分支,然后对于这些抽象类中的每一个都是提供所有其余方法的实现的具体类。

封装是一种技术。它可能是也可能不是为了帮助抽象,但它肯定是关于信息隐藏和/或组织。它要求数据和功能以某种方式分组 - 当然,良好的OOP实践要求它们应该通过抽象进行分组。但是,还有其他用途可以帮助维护等。


29
投票

封装是抽象的一部分,或者我们可以说它是抽象的一个子集

它们是不同的概念。

  • 抽象是精炼对象的所有不需要/不重要的属性并且仅保留最适合您的域的特征的过程。 例如。对于一个人:你决定保留名字和SSN。年龄,身高,体重等被忽略为无关紧要。 抽象是你的设计开始的地方。
  • 封装是下一步,它可以识别适合您在抽象过程中保留的属性的操作。它是数据与作用于它们的操作的关联。 即数据和方法捆绑在一起。

24
投票

封装将不必要的数据隐藏在胶囊或单元中

抽象显示了对象的基本特征

封装用于从外部类和接口隐藏其成员。使用c#.like public,private,protected等提供的访问修饰符。示例:

Class Learn
{
  private int a;         // by making it private we are hiding it from other
  private void show()   //class to access it
  {
   console.writeline(a);
  }
}

这里我们将数据包装在一个单元或胶囊中,即Class。

抽象与封装正好相反。

抽象用于向用户显示重要且相关的数据。最好的现实世界的例子在手机中,你会看到它们不同类型的功能,如相机,MP3播放器,调用功能,录音功能,多媒体等。它是抽象的,因为你只看到相关信息而不是内部工程。

 abstract class MobilePhone
    {
        public void Calling();       //put necessary or essential data
        public void SendSMS();       //calling n sms are main in mobile
    }

    public class BlackBerry : MobilePhone   // inherited main feature
    {
        public void FMRadio();            //added new
        public void MP3();
        public void Camera();
        public void Recording();

    }

14
投票

抽象是一个非常通用的术语,软件中的抽象不仅限于面向对象的语言。字典定义:“将事物视为一般质量或特征的行为,除了具体的现实,特定的对象或实际的实例”。

汇编语言可以被认为是机器代码的抽象 - 汇编表达了机器代码的基本细节和结构,但是你不必考虑所使用的操作码,代码在内存中的布局,使得跳转到正确的地址等

您的操作系统的API是底层机器的抽象。您的编译器提供了一个抽象层,使您免受汇编语言的细节。操作系统内置的TCP / IP堆栈抽象了网络上传输比特的细节。如果你一直走到原始硅片,设计你的CPU的人就是用“二极管”和“晶体管”编写的电路图,这是电子如何穿过半导体晶体的抽象。

在软件中,一切都是抽象的。我们构建了模拟或模拟现实某些方面的程序,但必要时我们的模型总是抽象出“真实的东西”的一些细节。我们在抽象层上构建图层,因为这是我们完成任务的唯一方法。 (想象一下,你试图制作一个数独求解器,你必须只用半导体晶体来设计它。“好吧,我需要一块N型硅......”)

相比之下,“封装”是一个非常具体和有限的术语。这个问题的其他一些答案已经给出了很好的定义。


13
投票

5年后回答我自己的问题,因为我觉得它仍然需要更多的细节

抽象:

技术定义: - 抽象是隐藏不必要细节(复杂或简单)的概念,仅显示对象的基本特征。这里没有实现它只是一个概念

这实际上意味着什么: - 当我说我的公司需要一些媒体/设备,以便员工可以连接到客户。这是最纯粹的抽象形式(如java中的界面),因为该设备/媒体可以是电话或互联网或Skype或亲自或电子邮件等。我不会深入了解设备/媒体的细节

即使我说我的公司需要一些媒体/设备,以便员工可以通过语音通话连接到客户。然后我也说抽象,但在较低的水平,因为设备/媒体可以是电话或Skype或其他等

现在,当我说我的公司需要一些电话,以便员工可以通过语音通话连接到客户。然后我也说抽象,但在较低的水平,因为手机可以是任何公司,如iPhone或三星或诺基亚等

封装: - 它基本上是在私有,公共,受保护等修饰符的帮助下隐藏对象的状态(信息)。我们只在需要时通过公共方法公开状态。

它实际上意味着什么: - 现在,当我说我的公司需要一些iphone,以便员工可以通过语音通话连接到客户。现在我在谈论一些具体的对象(如iphone)。即使我在这里也没有深入了解iphone,但iphone有一些与设备/媒体没有相关的状态/混凝土信息/实现。当我说具体对象时,实际上它意味着任何具有一些(不完全像java抽象类)实现/信息的对象。

所以iphone实际上在这里使用封装作为策略隐藏其状态/信息并仅暴露它认为应该暴露的那些。因此,抽象和封装都隐藏了一些不必要的细节,但在概念层面上是抽象,在实现层面实际上是封装

这是基于这篇文章及以下文章中的答案的要点

  1. difference between abstraction and encapsulation?
  2. encapsulation vs abstraction real world example

5
投票

封装 - 隐藏类的组件以防止从外部直接访问的过程。它通过使用“private”修饰符来防止从其他类或对象直接访问某些类成员(数据字段或方法),同时通过公共成员(接口)提供对这些私有成员的访问。这使得班级成员受到保护,因为人体器官被隐藏/封装在皮肤或一些盾牌之下。

抽象 - 编写OOP程序时必须遵循一个原则,即“你必须在课程中只包含对程序任务感兴趣的组件”。例如:对象学生有很多角色作为人:名字,年龄,体重,头发颜色,眼睛颜色等。但是,当你在OOP中创建一个与学生一起工作的课程时,你应该只包括那些真正的角色对于学生数据库的问题:C ++中的名称,年龄,专业,级别,标记等等你可以通过使用修饰语“virtual”和类中的任何方法来创建抽象类,这将使它无法直接使用,但你可以从中派生其他类,并根据任务添加所需成员,为其成员创建实现。


4
投票

这就是我理解它的方式:

在面向对象编程中,我们有一些叫做类的东西。它们适用于什么?它们存储一些状态并存储一些改变该状态的方法,即它们封装状态及其方法。

它(类)不关心它自己或其内容的可见性。如果我们选择隐藏状态或某些方法,那就是信息隐藏。

现在,采取继承的方案。我们有一个基类和一些派生(继承)类。那么,基类在这做什么?它从派生类中抽象出一些东西。

他们都不一样吧?但是,我们将它们混合起来编写好的面向对象程序。希望能帮助到你 :)


3
投票

抽象描述了特定于上下文的简化表示;它忽略了与上下文无关的细节,并包含了上下文重要的细节。

封装限制了对某些部分的外部访问,并将该事物的状态与使用该状态的过程捆绑在一起。


以人为例。在外科手术中,有用的抽象忽略了一个人的宗教信仰,并包括了人的身体。此外,人们用他们使用那些记忆的思维过程来封装他们的记忆。抽象不需要封装;例如,一个人的绘画既不隐藏其部分也不捆绑程序与其状态。而且,封装不需要相关的抽象;例如,真实的人(不是抽象的人)用他们的新陈代谢包裹他们的器官。

© www.soinside.com 2019 - 2024. All rights reserved.