“数据隐藏”和“封装”有什么区别?


29

我正在阅读“实践中的Java并发性”,有人说:“幸运的是,相同的面向对象技术可以帮助您编写组织良好,可维护的类(例如封装和数据隐藏),也可以帮助您创建线程安全的类。”

问题#1-我从未听说过数据隐藏,也不知道它是什么。

问题2-我一直认为封装使用的是私有vs公共,实际上是在隐藏数据。

您能否解释一下什么是数据隐藏以及它与封装有何不同?


2
阅读Code Complete第二版。它将回答您的许多问题。
Shiplu Mokaddim


此链接可帮助您了解此 信息隐藏设计原则,并指定应将设计决策隐藏在系统的其余部分中,以防止意外耦合。它应该告知您封装事物的方式,但是当然不是必须的。 封装是一种编程语言功能。
阿披耶特(Abhijeet)2016年

Answers:


19

数据和信息隐藏是计算机科学与软件工程中的更广泛概念。它指的是计算机程序的那些可能更改的部分一定不能从其他模块/客户端访问。

封装是在面向对象范例中找到的一个术语,是指将数据保留在私有字段中并仅通过方法对其进行修改。

因此,封装可以被视为在面向对象的系统中实现数据隐藏的一种方式


1
谢谢您的回复。我仍然不明白,为什么如果数据隐藏是相同的,但是比封装要宽一些,那么在书中将其称为具有相似的广泛性,而不是包含另一个。
dhblah 2012年

作者可能与数据隐藏和信息隐藏有所不同,因为数据隐藏仅隐藏数据结构-私有字段-而信息隐藏可能是指仅通过接口进行的封装实现细节(例如,使用的算法)通信。
m3th0dman 2012年

2
您可以拥有一个而没有另一个-看看Python,那里根本没有数据隐藏(没有私有或受保护的属性之类的东西)。
Latty

@Lattyware的观点非常真实和重要。一个人也可以封装(根据您的定义,由于我在这里的描述,我反对),而无需隐藏任何内容,即通过为每个成员盲目暴露一个琐碎的getter和setter方法。这不会隐藏任何内容,也不会阻止任何内容,但是可以满足对字母封装的常见定义。

1
封装不是将数据保留在私有字段中,而是隐藏了更多信息。一般而言,封装是将信息/数据和方法放在一起(封装)到一个类中的概念。
nbro

6

封装和数据隐藏是相关术语。重要的是要了解它们是与抽象有关的布奇(Booch)等。等 面向对象分析与设计应用解释,

抽象和封装是互补的概念:抽象着重于对象的可观察行为,而封装着重于引起这种行为的实现。封装通常是通过信息隐藏(而不仅仅是数据隐藏)来实现的,信息隐藏是一种隐藏对象的所有秘密的过程,这些秘密不影响对象的本质特征。通常,对象的结构以及其方法的实现都是隐藏的。


5

创建一个类包括封装的概念。创建类时,您将数据和行为放入类内,并且该类成为我们称为对象的一个​​单元。因此,数据隐藏是封装的一部分。


4

维基百科

在编程语言中,封装用于指两个相关但截然不同的概念之一,有时还指其组合:

  • 一种语言机制,用于限制对某些对象组件的访问。
  • 一种语言构造,它有助于将数据与对数据进行操作的方法(或其他功能)捆绑在一起。

一些编程语言研究人员和学者将第一种含义单独或与第二种含义结合使用,作为面向对象编程的显着特征,而其他提供词汇闭包的编程语言则将封装视为与对象定向正交的语言的特征。

第二个定义的动机是,在许多OOP语言中,组件的隐藏不是自动的或可以被覆盖的; 因此,信息隐藏被那些喜欢第二种定义的人定义为一个单独的概念。


感谢您的回复。后续问题:1)Java编程语言是否具有与封装相关的第二个概念所指的功能?2)我不明白为什么覆盖数据隐藏很重要。例如,在Java中,您可以通过反射访问任何字段(公共或私有)。
dhblah 2012年

@Software Engeneering学习者:作为源代码构造的类表示第二个概念。至于信息隐藏,关键是限制数据范围通常是基于特定且独立的语言机制。
Michael Borgwardt 2012年

2

它们经常在讨论中互换使用,我经常认为它们可以共同实现相同的目的,尽管以下内容可能并不完全准确,但如果需要加以区别,它可能会提供一些有意义的区别:

在谈论封装时,通常将其实现为过程/功能机制。底层状态有某种类型的防护,通过防护的访问要求遵循某些协议以提供访问权限(读取或更改所需状态)。封装还提供了因访问而发生副作用的机会(例如级联状态更改,或在读取或更改感兴趣的事物时通知/引发事件/发出信号),因此可以启动后续操作。同样,我经常将封装视为一个概念,将其作为过程来实现。

我看到数据隐藏的概念与封装的目的相似。但是,该机制是结构性的,并且在不同的级别上运行。实际上,不是通过过程提供保护和副作用机制,而是通过语言和运行时的结构机制来保护和影响状态。这些类型的保护措施包括可见性子句,类型定义,继承等。您可以从结构受保护的对象中利用的副作用又取决于语言和运行时:可能是对象激活,引用计数或类似的东西。


0

它们通常可以互换使用。但是请注意上面Booch的话说:“封装通常是通过信息隐藏实现的……”,即在大多数情况下,但并非总是如此。

请注意,Python允许在类中汇总数据,但不允许私有变量。因此可以说Python提供了封装而不隐藏数据。

您可以通过使所有成员变量都在Java中执行相同的操作public,但是除了让每个人都心脏病发作之外,您还失去了数据隐藏的好处...即通过限制对对象状态的访问来保留对象的语义。


0

在OO中,封装是将信息保存在对象内的位置。例如,一个Person具有name和的Person的客户(即您)通过公共字段或访问器方法知道 Person拥有一个名称。而且,希望您不必将这些名称也保存在某些全局名称数组中,等等。因此,这是避免难以管理的意大利面条式代码的重要一步。但是客户端仍然需要了解有关Person如何处理名称的某些知识:例如,空格或逗号分隔?

数据隐藏Person一个具有名称字段的地方,但至少在理论上,没人知道。该字段是私有的,没有公共访问器方法。客户端可以通过数据库记录,XML,HTTP POST等传递名称,但是Person处理名称的内部工作是一个“黑匣子”。Person的未来实现可以自由更改,例如切换为使用a firstName和a lastName

在理想的世界中,数据隐藏优于封装,但并非所有世界都理想。:-)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.