封装与信息隐藏

use*_*616 18 java oop encapsulation information-hiding

Ecapsulation和信息隐藏之间究竟有什么区别?

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

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

public Class IsThisEncapsulation
{
    public int age;

    public void setAge(int age)
    {
       this.age=age;
    }

    public int getAge()
    {
       return age;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

现在是否会让上述类私有领域的'年龄'实现信息隐藏?

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

Nan*_*ale 17

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

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

信息隐藏:

- >限制访问某些对象组件的机制.您的上述示例是信息隐藏的情况,如果您age私有.


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

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

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

参考:wikipage


Sum*_*ngh 8

抽象 - 信息 - 隐藏 - 封装

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

信息隐藏:

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

"抽象可以用作识别应隐藏哪些信息的技术."

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

封装:

"它[...]指的是围绕一些东西建造一个胶囊,在一个概念屏障的情况下." - [Wirfs-Brock等,1990]

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

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

  • 如果我可以引用 Parnas,我会 5。 (2认同)

Jos*_*son 7

封装和信息隐藏是紧密联系在一起的概念,尽管它们的确切定义取决于与您交谈的人。

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

Zilles(1973)创造了“封装”一词,描述了使用过程来控制对底层数据的访问,以降低系统复杂性并保护数据免遭危险的修改。

随后,Parnas(1978)将信息隐藏和封装(和抽象)描述为同义词,这些术语描述了隐藏可能更改的系统细节的隐患。但是,已经在信息隐藏和封装之间进行了区分,例如Micallef(1987),他将封装描述为“信息隐藏的严格执行”。一些作者,例如Cohen(1984)以及Abreu和Melo(1996)将“封装机制”描述为允许信息隐藏,尤其是在面向对象的编程语言中。

Meyers(2000)认为,一段代码的封装程度取决于更改后将被破坏的代码量。从这个意义上说,私有数据和方法被封装得越多,可以访问它们的方法就越少。相反,公共数据和方法是完全未封装的,因为访问它们的代码量是未知的。

相反,Rogers(2001)认为封装只是一种语言机制,它允许数据与对数据进行操作的方法捆绑在一起。他声称封装从根本上与信息隐藏无关。但是,该定义与他的文章发表前的28年中该术语在学术文献中的几乎所有用法都背道而驰。目前这种用法的一些其他的例子,例如射手和斯廷森(1995年),但他们却并不多见,而不是特别显着。

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

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

public class BankAccount {
    public int dollars;
}
Run Code Online (Sandbox Code Playgroud)

此类的实现是完全未封装的,这意味着它是不灵活的(例如,将来我们不能轻易增加对单个美分的支持)并且是不安全的(例如,帐户可以更改为负数)。但是,如果我们将数据隐藏在方法的正式定义的接口后面,那么我们将获得灵活性和安全性。

public class BankAccount {
    private int dollars;

    public void deposit(int dollars) {
        this.dollars += Math.max(0, dollars);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在可以更好地封装该类,因为我们已经隐藏了有关其基础实现的信息。

  • 这个答案比公认的答案得到了更好的支持。+1 (3认同)
  • 这个答案是对这些想法的有用调查以及一组出色的参考资料。读者会发现追寻并阅读原始材料是非常有益的。也就是说,我将挑选参考文献。:-) 参考文献“Micallef (1987)”实际上是 Alan Snyder 的链接,“封装软件系统的继承和开发”,Shriver/Wegner 书中的一章,_面向对象编程的研究方向_,麻省理工学院出版社, 1987年。 (2认同)
  • 我认为引用“Micallef (1987)”是指 Micallef,_面向对象编程语言中的封装、可重用性和可扩展性_,哥伦比亚大学计算机科学技术报告 CUCS-285-87,1987 年。 https://academiccommons.columbia .edu/doi/10.7916/D8TT4ZZD(提供 PDF)。看起来引用来自 Micallef,因此该报告可能是预期的链接。然而,斯奈德的参考似乎也相关。 (2认同)

Eds*_*Eds 5

这些之间存在细微差别,我喜欢Steve Freeman和Nat Pryce撰写的"面向测试的面向对象软件的成长"一书中的描述:

哪个说:

封装

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

信息隐藏

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