数据隐藏是封装的一种形式,但并非所有封装都是数据隐藏。

4
我已经阅读了100多个链接并探索了所有SO上的问题,但是:(仍然无法理解数据隐藏和封装之间的区别。在阅读this answer时,我读到了这一行数据隐藏是封装,但并非所有封装都是数据隐藏。所以经过大量研究,我发现1)数据隐藏通过封装实现或者它是封装的一种形式(我是对的吗?)2)如果是的话,应用访问限定符就是数据隐藏(也是封装),但是只有封装而不是数据隐藏的机制是什么?

2
从信息隐藏的维基百科文章中:“封装术语经常与信息隐藏交替使用。然而,并不是所有人都同意两者之间的区别;一个人可能认为信息隐藏是原则,而封装是技术。” - 我怀疑你会得到一个明确的答案... - Jon Skeet
我认为你在纠缠于细节。数据隐藏和封装基本上是同一件事情。 - Oliver Watkins
@JonSkeet 所以我们可以简单地说,封装就是数据隐藏的全部,而数据隐藏就是封装的全部。 - Despicable
1
@可鄙的:我想我能确定的是,不同的人会以不同的方式解释这些术语。 - Jon Skeet
1
@JonSkeet,我需要“C#深度剖析”的作者的意见?他怎么说? - Despicable
显示剩余3条评论
3个回答

4

简短回答:

1) 可以通过不使用封装来实现数据隐藏,一个例子是类中的私有常量,该常量不会被任何“getter”返回。

2) 应用访问修饰符可能是数据隐藏和封装。您可以实现封装但无法实现数据隐藏,当您公开数据但仅允许由getter和setter修改时。

更详细的解释:

数据隐藏和封装是非常不同的概念,但相关联。数据隐藏是关于不泄露您的类的任何用户实现细节,而封装则是防止数据意外更改。

我找到的最好的解释在书籍“Growing Object Oriented Systems Guided by Tests”中(第49页)

作者说,封装几乎总是一件好事,但是数据隐藏可能在错误的位置,他们给出了以下示例:

  • 封装Loader类中缓存的数据结构
  • 封装PrivacyPolicy类的应用程序日志文件名称

以上两个示例听起来都很合理,但是从数据隐藏的角度来看:

  • 在Loader类中隐藏缓存的数据结构
  • 在PrivacyPolicy类中隐藏应用程序的日志文件名称

在缓存的示例中,隐藏它是有意义的。但是对于应用程序日志文件名称,隐藏它就没有意义。


数据隐藏是指不向类的任何用户泄露实现细节,而封装则是防止数据发生意外更改。+1 - Despicable
很棒的答案,非常清晰。现在我只想知道一件事情,然后我就会接受你的答案。1)从“封装可以防止数据意外更改”的那一行中,这意味着通过应用getter和setter,我们可以轻松实现封装,对吗?(如果您有其他示例,请分享)。2)从“数据隐藏是关于不泄露类的任何用户的实现细节”这一行中,这意味着我们不仅可以通过封装,还可以通过抽象来实现数据隐藏?(如果您有其他数据隐藏的示例,请分享) - Despicable
如果数据隐藏是关于不泄露实现细节,那么数据隐藏和抽象之间有什么区别?它们是相同的吗? - Samra

0

抽象化

  • 专注于基本方面并隐藏背景/实现细节

  • 专注于对象的外部视图。例如:堆栈类[抽象化侧重于类推送、弹出提供的服务]

  • 抽象化允许捕获整个对象行为,不多也不少。
  • 它关注对象能做什么
  • 它有助于基于责任驱动方法识别类[将系统分类为一组基于类执行的责任的对象]

封装

  • 将对象的状态和行为捆绑成单个单位
  • 通过定义类来实现[识别状态和行为,并将这两个内容放在一起成为一个类]
  • 使得对象的状态和行为可以集中在一起
  • 它不隐藏实现细节,其目的是识别状态和行为,并将这些东西放在一起
  • 它关注对象的内部视图,而抽象化关注对象的外部视图
  • 封装有助于实现抽象化

信息隐藏

  • 封装必须只允许公开必要的服务,信息隐藏是与封装相关的概念,需要隐藏对象的实现细节
  • 信息隐藏和封装不同

封装是确定将对象的哪些状态和行为放在一起的决策,而信息隐藏是决定向用户公开哪些封装项以及不向用户公开哪些封装项的决策。


0

封装可以隐藏复杂性。就像我们创建getter和setter一样。

但是数据隐藏意味着隐藏某些内容,在Java中,我们可以使用访问修饰符来完成。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接