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


当前回答

抽象是广义的术语。即封装是抽象的子集。

Abstraction Encapsulation
It solves an issue at the design level. Encapsulation solves an issue at implementation level.
hides the unnecessary detail but shows the essential information. It hides the code and data into a single entity or unit so that the data can be protected from the outside world.
Focuses on the external lookout. Focuses on internal working.
Lets focus on what an object does instead of how it does it. Lets focus on how an object does something.
Example: Outer look of mobile, like it has a display screen and buttons. Example: Inner details of mobile, how button and display screen connect with each other using circuits.

示例:解决方案架构师是创建整个解决方案的高级抽象技术设计的人,然后将该设计移交给开发团队进行实现。 在这里,解决方案架构师充当抽象,而开发团队充当封装。


举例:用户数据的封装(组网)

图片由

Abstraction (or modularity) – Types enable programmers to think at a higher level than the bit or byte, not bothering with low-level implementation. For example, programmers can begin to think of a string as a set of character values instead of as a mere array of bytes. Higher still, types enable programmers to think about and express interfaces between two of any-sized subsystems. This enables more levels of localization so that the definitions required for interoperability of the subsystems remain consistent when those two subsystems communicate. Source

Java示例

其他回答

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

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

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

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

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

抽象是我们将要执行的实现的契约。实现可能会在一段时间内发生变化。各种实现本身可能隐藏,也可能不隐藏,而是隐藏在抽象后面。

假设我们在一个接口中定义了一个类的所有api,然后要求代码的用户依赖于该接口中定义的api。我们可以自由地改进或修改实现,但必须遵守设定的合同。用户与我们的实现没有耦合。

我们在抽象中暴露所有必要的规则(方法),规则的实现留给实现者实体,实现也不是抽象的一部分。正是签名和声明使抽象成为现实。

封装只是通过减少对状态和行为的访问来隐藏内部细节。封装的类可能有也可能没有定义良好的抽象。

java.util.List是java.util.ArrayList的抽象。使用非公共访问修饰符标记的java.util.ArrayList的内部状态是封装。

Edit Suppose a class Container.nava implements IContainer , IContainer may declare methods like addElement, removeElements, contains, etc. Here IContainer represents the abstraction for its implementing class. Abstraction is declaring the APIs of the class or a module or a system to the outer world. These APIs become the contract. That system may be or may not be developed yet. The users of the system now can depend on the declared APIs and are sure any system implementing such a contract will always adhere to the APIs declared, they will always provide tge implementation for those APIs. Once we are writing some concrete entity then deciding to hide our internal states is encapsulation

我读得越多,就越困惑。所以,我的理解是:

封装:

我们通常从外面看到手表,它的组件被封装在它的身体里。我们对不同的操作有某种控制。这种隐藏细节和公开控制(例如设置时间)的方式就是封装。

抽象:

到目前为止,我们一直在谈论手表。但我们没有具体说明是哪种手表。可以是数字的,也可以是模拟的,可以是手用的,也可以是墙用的。有很多可能性。我们所知道的是,这是一块手表,它显示时间,这是我们唯一感兴趣的东西,时间。这种隐藏细节和公开通用特性或用例的方法就是抽象。

抽象和封装过程都会生成接口。

通过封装生成的接口隐藏了实现细节。

与抽象之前相比,通过抽象生成的接口可以适用于更多的数据类型。

这里的大多数答案都关注于OOP,但封装开始得更早:

Every function is an encapsulation; in pseudocode: point x = { 1, 4 } point y = { 23, 42 } numeric d = distance(x, y) Here, distance encapsulates the calculation of the (Euclidean) distance between two points in a plane: it hides implementation details. This is encapsulation, pure and simple. Abstraction is the process of generalisation: taking a concrete implementation and making it applicable to different, albeit somewhat related, types of data. The classical example of abstraction is C’s qsort function to sort data: The thing about qsort is that it doesn't care about the data it sorts — in fact, it doesn’t know what data it sorts. Rather, its input type is a typeless pointer (void*) which is just C’s way of saying “I don't care about the type of data” (this is also called type erasure). The important point is that the implementation of qsort always stays the same, regardless of data type. The only thing that has to change is the compare function, which differs from data type to data type. qsort therefore expects the user to provide said compare function as a function argument.

封装和抽象是密切相关的,因此您可以认为它们确实是不可分割的。就实际而言,这可能是对的;也就是说,这里有一个不太抽象的封装:

class point {
    numeric x
    numeric y
}

我们封装了点的坐标,但是我们没有实质性地将它们抽象出来,只是在逻辑上对它们进行分组。

这里有一个抽象的例子,它不是封装:

T pi<T> = 3.1415926535

这是一个具有给定值(π)的泛型变量pi,声明并不关心变量的确切类型。诚然,我很难在真实的代码中找到这样的东西:抽象实际上总是使用封装。然而,上面的内容在c++(14)中确实存在,通过变量模板(=变量的通用模板);使用稍微复杂一点的语法,例如:

template <typename T> constexpr T pi = T{3.1415926535};