封装和抽象之间的确切区别是什么?


当前回答

class Aeroplane : IFlyable, IFuelable, IMachine
{ // Aeroplane's Design says:
  // Aeroplane is a flying object
  // Aeroplane can be fueled
  // Aeroplane is a Machine
}
// But the code related to Pilot, or Driver of Aeroplane is not bothered 
// about Machine or Fuel. Hence,
// pilot code:
IFlyable flyingObj = new Aeroplane();
flyingObj.Fly();
// fighter Pilot related code
IFlyable flyingObj2 = new FighterAeroplane();
flyingObj2.Fly();
// UFO related code 
IFlyable ufoObj = new UFO();
ufoObj.Fly();
// **All the 3 Above codes are genaralized using IFlyable,
// Interface Abstraction**
// Fly related code knows how to fly, irrespective of the type of 
// flying object they are.

// Similarly, Fuel related code:
// Fueling an Aeroplane
IFuelable fuelableObj = new Aeroplane();
fuelableObj.FillFuel();
// Fueling a Car
IFuelable fuelableObj2 = new Car(); // class Car : IFuelable { }
fuelableObj2.FillFuel();

// ** Fueling code does not need know what kind of vehicle it is, so far 
// as it can Fill Fuel**

其他回答

封装隐藏了实现细节,这些细节可能是通用的,也可能不是专门的行为。

抽象提供了一种泛化(例如,在一组行为之上)。

这里有一个很好的阅读:抽象、封装和信息隐藏,作者是Object Agency的Edward V. Berard。

我认为封装是实现抽象的一种方式。看看下面的链接。

抽象和封装

这些有些模糊的概念并不是计算机科学和编程所独有的。我想提供一些额外的想法,可能有助于其他人理解这些重要的概念。


简短的回答

封装——隐藏和/或限制对系统某些部分的访问,同时暴露必要的接口。

抽象性——从具体的现实、具体的对象或实际实例中去除某些特征,从而降低复杂性。

主要的相似之处在于,这些技术旨在提高理解能力和实用性。

主要的区别在于抽象是一种更简单地表示事物的方法(通常是为了使表示更广泛地适用),而封装是一种改变其他事物与事物交互方式的方法。


长回答

封装

下面是一个封装的例子,希望能让大家更清楚:

这里我们有一个Arduino Uno,还有一个Arduino Uno。封装是封装的一个很好的代表。

封装旨在保护某些组件不受外部影响和知识的影响,并公开其他组件应该与之交互的组件。在编程术语中,这涉及到通过访问修饰符隐藏信息,访问修饰符改变了某些变量和/或属性可以读写的程度。

但除此之外,封装还旨在更有效地提供这些外部接口。对于我们的Arduino示例,这可能包括漂亮的按钮和屏幕,这使得用户与设备的交互更加简单。它们为用户提供了简单的方法来影响设备的行为,并获得有关其操作的有用信息,否则将非常困难。

在编程中,这涉及到将各种组件分组为可分离的结构,如函数、类或对象。它还包括提供与这些构造交互的方法,以及获取关于它们的有用信息的方法。

封装在许多其他方面帮助程序员,尤其是提高代码的可维护性和可测试性。

抽象

尽管这里有许多其他的答案将抽象定义为泛化,但我个人认为这个定义是错误的。我想说泛化实际上是一种特定类型的抽象,而不是反过来。换句话说,所有的概括都是抽象,但并非所有的抽象都一定是概括。

以下是我对抽象的看法:

你会说这个图像是一棵树吗?很有可能你会。但它真的是一棵树吗?当然不是!它是一堆像素,看起来像我们可能称之为树的东西。我们可以说它代表了一棵真实树的抽象。注意,树的一些可视化细节被省略了。此外,它不生长,不消耗水,也不产生氧气。怎么可能呢?它只是屏幕上的一堆颜色,由计算机内存中的字节表示。

这就是抽象的本质。这是一种简化事物的方法,这样它们就更容易理解。你脑子里的每一个想法都是对现实的抽象。你脑海中的树和这张图片一样都不是真正的树。

在编程中,我们可以通过创建一个Tree类来利用这一点,其中包含模拟生长、水消耗和氧气生产的方法。我们的创造将代表我们对实际树木的体验,并且只包含我们真正关心的特定模拟元素。我们使用抽象作为一种用字节和数学来表示我们经验的方式。

抽象类

编程中的抽象还允许我们考虑几个“具体”对象类型(实际存在的类型)之间的共性,并在唯一的实体中定义这些共性。例如,我们的Tree类可以继承一个抽象类Plant,它有几个属性和方法适用于我们所有类植物,但删除了那些特定于每种植物类型的属性和方法。这可以显著减少代码重复,并提高可维护性。

抽象类和普通类的实际区别在于,抽象类在概念上没有“真正的”实例。构造一个Plant对象没有意义,因为它不够具体。每一种“真正的”植物也是一种更具体的植物类型。

此外,如果我们希望程序更加实际,我们可能需要考虑Tree类本身可能过于抽象的事实。实际上,每个Tree都是一种更具体的Tree类型,因此我们可以为这些类型创建类,例如Birch、Maple等,它们继承自我们的Tree类(现在可能是抽象的)。

JVM

另一个抽象的好例子是Java虚拟机(JVM),它为Java代码的运行提供了一个虚拟或抽象的计算机。它从本质上拿走了系统中所有平台特定的组件,并提供了一个抽象的“计算机”接口,而不考虑任何特定的系统。

的区别

封装与抽象的不同之处在于,它与事物的“真实”或“准确”没有任何关系。它不会删除某些组件以使其更简单或更广泛地适用。相反,它可以隐藏某些组件来实现类似的目的。

抽象让您关注对象做了什么,而不是它是如何做的 封装意味着隐藏对象如何做某事的内部细节或机制。

就像你开车时,你知道油门踏板的作用,但你可能不知道它背后的过程,因为它是封装的。

让我用c#举个例子。假设你有一个整数:

int Number = 5;
string aStrNumber = Number.ToString();

你可以使用像number . tostring()这样的方法,它返回数字5的字符表示,并将其存储在字符串对象中。该方法告诉您它做了什么,而不是如何做。

抽象和封装都是用来隐藏数据的。但是有很大的不同。

封装

封装是将数据和对数据进行操作的代码绑定或包装成一个称为Class的单元的过程。

封装在实现级别解决了问题。

在类中,可以使用私有或受保护的访问修饰符来隐藏数据。

抽象

抽象是隐藏无关细节的概念。换句话说,通过对用户隐藏不必要的细节,使复杂的系统变得简单。

抽象在设计层面解决了问题。

可以通过在Java中创建接口和抽象类来实现抽象。

在ruby中,你可以通过创建模块来实现抽象。

示例:我们使用(收集,映射,减少,排序…)方法的枚举模块与数组和ruby哈希。