封装与信息隐藏

Ecapsulation和Information Hiding之间究竟有什么区别?

我知道将字段设为私有然后制作字段的setter和getter是ecapsulation.However封装意味着这个?

假设我有一个如下所述的课程。

public Class IsThisEncapsulation { public int age; public void setAge(int age) { this.age=age; } public int getAge() { return age; } } 

现在是IsThisEncapsulation类是Encapsulation的一个例子吗?

现在是否会使上述class级中的“年龄”字段实现信息隐藏?

能否请您给我一些明确的例子,以帮助我清楚地区分这些概念?

嗯,我知道将字段设为私有,然后制作字段的setter和getter是封装。 但是,封装意味着这个吗?

—> Encapsulation是一个OOP概念,其中对象状态(类字段)和它的行为(方法)被包装在一起。 Java使用class提供封装。

信息隐藏:

– >限制访问某些对象组件的机制。 如果您将age设为私有,则上面的示例是信息隐藏的情况。


最初,信息/数据隐藏被认为是封装的一部分,封装的定义如下:

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

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

参考: wikipage

从抽象 – 信息 – 隐藏 – 封装

抽象和封装是互补的概念:抽象关注于对象的可观察行为……封装侧重于产生这种行为的实现……封装通常是通过信息隐藏来实现的,这是隐藏所有内容的过程。对象的秘密不会对其基本特征产生影响。

信息隐藏:

“它的界面或定义被选中以尽可能少地揭示它的内部运作。” – [Parnas,1972b]

“抽象可以用作识别应隐藏哪些信息的技术。”

“当人们无法区分隐藏信息和用于帮助识别哪些信息被隐藏的技术(例如,抽象)时,就会发生混淆。”

封装:

“它[…]指的是围绕某些东西建造一个胶囊,在一个概念屏障的情况下。” – [Wirfs-Brock等,1990]

“作为一个过程,封装意味着将一个或多个物品封闭在一个容器内。封装作为一个实体,是指包含(包含,封闭)一个或多个物品的包裹或shell。”

“如果封装与信息隐藏相同,那么人们可能会提出这样的论点:’封装的所有内容也都是隐藏的’。 这显然不是真的。“

这些之间存在细微的差别,我喜欢史蒂夫·弗里曼和Nat Pryce撰写的“由测试引导的面向对象软件的成长”一书中的描述:

哪个说:

封装

确保对象的行为只能通过其API进行影响。 它允许我们通过确保不相关组件之间没有意外的依赖关系来控制对一个对象的更改将对系统的其他部分产生多大影响。

信息隐藏

隐藏对象如何在其API的抽象背后实现其function。 它允许我们通过忽略与手头任务无关的低级细节来处理更高的抽象。

封装和信息隐藏是非常紧密相关的概念,尽管它们的精确定义取决于您与谁交谈。

Parnas(1971)首先描述了“信息隐藏”的概念,他提出应限制对信息的访问以减少系统的相互关联性。 他提出,这将有助于将系统拆分为模块,同时保持用户友好的外部接口,并允许在不影响客户端的情况下更改实现细节。

术语“封装”是由Zilles(1973)创造的,用于描述使用程序来控制对底层数据的访问,以降低系统复杂性并保护数据免受危险的修改。

随后, Parnas(1978)将信息隐藏和封装(和抽象)描述为同义词,描述了隐藏可能发生变化的系统细节。 然而,信息隐藏和封装之间已经有所区别,例如Micallef(1987) ,他将封装描述为“严格执行信息隐藏”。 一些作者,如Cohen(1984)和Abreu和Melo(1996)描述了“封装机制”,特别是在面向对象编程语言中,允许信息隐藏。

Meyers(2000)建议封装一段代码的程度取决于代码量如果发生变化就会被破坏。 从这个意义上讲,私有数据和方法的封装越多,访问它们的方法就越少。 相比之下,公共数据和方法完全没有封装,因为可以访问它们的代码量是未知的。

相反, Rogers(2001)认为封装只是一种语言机制,它允许数据与运行在该数据上的方法捆绑在一起。 他声称封装从根本上与信息隐藏无关。 然而,这一定义与他的文章发表前28年中学术文献中几乎所有术语的使用背道而驰。 还有一些这种用法的例子,例如Archer和Stinson(1995) ,但它们很少,而且不是特别值得注意。

总之,信息隐藏是指应隐藏信息,以便在不影响客户的情况下更改设计。 这允许增加灵活性和稳健性。 封装可以被认为与信息隐藏相同,但该术语通常用于描述信息隐藏的实际实现,尤其是在面向对象的编程中。

作为信息隐藏/封装的示例,请考虑以下类:

 public class BankAccount { public int dollars; } 

这个类的实现完全没有封装,这意味着它是不灵活的(例如,我们不能轻易地添加对未来个人美分的支持)和不安全(例如,帐户可能变为负面)。 但是,如果我们将数据隐藏在正式定义的方法接口背后,我们就会获得灵活性和安全性。

 public class BankAccount { private int dollars; public void deposit(int dollars) { this.dollars += Math.max(0, dollars); } } 

我们现在可以控制状态的修改方式,我们也可以在不破坏客户端代码的情况下更改实现:

 public class BankAccount { private int cents; public void deposit(int dollars) { deposit(dollars, 0); } public void deposit(int dollars, int cents) { this.cents += Math.max(0, 100 * dollars) + Math.max(0, cents); } } 

现在这个类被更好地封装了,因为我们隐藏了有关其底层实现的信息。

只看到他们的字面含义。 封装只是把东西放在一个袋子里。 即将所有属性和方法放在类中实现封装但是在某种程度上,您还可以通过封装实现信息隐藏。 访问修饰符不会在封装中起作用,而在信息隐藏中起作用。

回答你的问题:

信息隐藏:隐藏对象的基本部分,暴露内部实现的方式并暴露更高的抽象。 例如:在电视遥控器中,我们只接触与电视互动的按键,我们不知道里面有什么。

封装:封装是组合数据和方法,允许公共方法访问内部数据。 所以,是的,如果在你的课堂上,你将变量age,private,你将实现封装

一个简单的例子:

 class NoEncapsulationOrInformationHiding { public ArrayList widths = new ArrayList(); } class EncapsulationWithoutInformationHiding { private ArrayList widths = new ArrayList(); public ArrayList getWidths(){ return widths; } } class InformationHidingWithoutEncapsulation { public List widths = new ArrayList(); } class EncapsulationAndInformationHiding{ private ArrayList widths = new ArrayList(); public List getWidths(){ return widths; } } 

封装允许您检查对自己内部的访问,并提供执行此类访问的特定方法。 它没有专门解决泄漏的实施细节; 虽然您可以控制对该变量的访问,但您无法再控制客户端知道您使用ArrayList的事实,即使您稍后决定使用LinkedList也是如此。

信息隐藏 ,另一方面隐藏了使用ArrayList实现宽度的事实。 虽然客户端仍然可以找到您的实现方式(InformationHidingIsNotInformationErasing),但您不再负责支持该实现。 在这里阅读更多

– >封装允许我们提供对对象的某些部分的访问,同时限制访问其他部分。 换句话说,封装允许我们进行信息隐藏。

– >信息隐藏实际上是限制的过程或行为