封装与信息隐藏

时间:2012-12-17 11:23:12

标签: java oop encapsulation information-hiding

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的一个例子吗?

现在将上述类私有的字段'age'实现信息隐藏吗?

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

10 个答案:

答案 0 :(得分:15)

  

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

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

  

信息隐藏:

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


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

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

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

参考:wikipage

答案 1 :(得分:8)

来自abstraction-vs-information-hiding-vs-encapsulation

  

抽象和封装是互补的概念:抽象侧重于对象的可观察行为......封装侧重于产生这种行为的实现......封装通常是通过信息隐藏来实现的,这是一个过程。隐藏对其基本特征没有贡献的对象的所有秘密。

信息隐藏:

  

“选择其界面或定义以尽可能少地揭示其内部运作。” - [Parnas,1972b]

     

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

     

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

封装:

  

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

     

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

     

“如果封装与信息隐藏相同',那么人们可能会认为'封装的所有内容也都是隐藏的'。这显然不是真的。“

答案 2 :(得分:5)

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

其中说:

<强>封装

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

信息隐藏

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

答案 3 :(得分:4)

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

&#34;信息隐藏的概念&#34;最初由Parnas (1971)描述,他建议限制访问信息以减少系统的相互关联性。他提出,这将有助于将系统拆分为模块,同时保持用户友好的外部接口,并允许在不影响客户的情况下更改实施细节。

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

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

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

相反,Rogers (2001)表明封装只是一种语言机制,它允许数据与运行在该数据上的方法捆绑在一起。他声称封装从根本上与信息隐藏无关。然而,这一定义与他的文章发表前28年中学术文献中几乎所有术语的使用背道而驰。 这个用法的一些其他例子,例如Archer and 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);
    }
}

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

答案 4 :(得分:1)

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

答案 5 :(得分:1)

来自 Edward Berard 的文章 Abstraction, Encapsulation, and Information Hiding

<块引用>

结论

抽象、信息隐藏、封装是很不一样的, 但高度相关的概念。有人可能会争辩说,抽象是一种 帮助我们确定哪些特定信息应该是的技术 可见,哪些信息应该隐藏。然后封装 以隐藏的方式包装信息的技术 应该隐藏什么,并使预期的内容可见 可见。

不难看出抽象、信息隐藏和 封装变得相互混淆。此外,人们可以 争辩说,不管它们的“字典定义”如何,这些术语 在软件工程的背景下已经演变出新的含义, 例如,与“范式”大致相同。 (参见,例如,[Kuhn, 1962]。)但是,可以提出一个更有力的论据来保持 概念和术语是不同的。

换句话说:

  • 抽象是一种选择技术(什么信息应该可见/隐藏);
  • 封装是一种表示技术(如何使信息可见/隐藏)。
<块引用>

我已经读到封装意味着将数据和应该对它们进行操作的过程捆绑在一起。如果是这样,下面的类是否实现了封装?

将数据和应该对它们进行操作的过程捆绑在一起是数据封装(也称为面向对象编程),即一种隐藏数据的技术,因为无数的过程可以对可见数据进行操作。在您的类中,数据属性 age 是可见的,因为它被声明为 public,所以这不是数据封装。

<块引用>

现在声明数据属性 age private 会实现信息隐藏吗?

就是数据封装,即数据隐藏。

答案 6 :(得分:0)

回答你的问题:

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

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

答案 7 :(得分:0)

一个过于简单的例子:

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;
  }
}

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

另一方面,

信息隐藏隐藏了您使用ArrayList来实现宽度的事实。尽管客户端仍然可以找到实现方式(InformationHidingIsNotInformationErasing),但您不再负责支持该实现。 阅读更多here

答案 8 :(得分:0)

这是当您不实现信息隐藏,封装或它所调用的内容时发生的情况。当您在角落中某个认为独立的地方更改某些内容时,就会发生坏事。其次,当您想更改系统中使用的第三方库时,您会发现系统中到处都有引用,您必须在不重构整个内容的情况下才能移动它们。例如,您要升级数据访问库版本(当我想更新ODP.net版本时遇到了这个问题),您估计工作在考虑要修改应该引用数据库的DataAccess类。客户端库。但是您发现,每个业务类都为数据库客户端库创建了一个引用。现在您必须更新60个程序集的引用,而不是一个:( Information leaking

当您向客户端公开内部逻辑时,也会发生同样的事情。例如,您有一个函数EnrollMember(string flag),您接受“ A”,“ B”作为有效标志,并在该函数内执行一些逻辑。当您以后想要更改此功能时,如果不通知客户就无法执行此操作。

答案 9 :(得分:-1)

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

- &GT;信息隐藏实际上是限制的过程或行为