28

信息隐藏封装有什么区别?

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

class IsThisEncapsulation {
    public int age;

    public int getAge() {
        return this.age;
    }

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

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

4

9 回答 9

22

好吧,我知道将字段设为私有,然后将字段的 setter 和 getter 设为封装。然而,封装仅意味着这个吗?

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

信息隐藏:

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


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

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

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

参考:维基页面

于 2012-12-17T11:55:30.157 回答
22

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

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

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

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

于 2016-09-14T20:43:55.253 回答
9

抽象与信息隐藏与封装

抽象和封装是互补的概念:抽象关注对象的可观察行为……封装关注引起这种行为的实现……封装通常通过信息隐藏来实现,即隐藏所有信息的过程不影响其本质特征的对象的秘密。

信息隐藏:

“选择它的界面或定义是为了尽可能少地揭示其内部运作。” ——[帕纳斯,1972b]

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

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

封装:

“它 [...] 是指围绕一些事物集合构建一个胶囊,在这种情况下是一个概念障碍。” — [Wirfs-Brock 等人,1990 年]

“作为一个过程,封装是指将一件或多件物品封装在 […] 容器内的行为。封装作为一个实体,是指容纳(包含、封装)一件或多件物品的包装或外壳。”

“如果封装是‘与信息隐藏一样’,那么人们可能会提出‘所有被封装的东西也被隐藏’的论点。这显然不是不正确的。”

于 2012-12-17T11:24:57.353 回答
5

它们之间有细微的差别,我喜欢 Steve Freeman 和 Nat Pryce 写的“Growing Object-Oriented Software Guided by Tests”一书中的描述:

其中说:

封装

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

信息隐藏

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

于 2012-12-17T11:28:43.017 回答
1

只看他们的字面意思。封装只是把东西放在一个袋子里。即把所有的属性和方法都放在一个类中实现了封装,但是在一定程度上你也通过封装实现了信息隐藏。访问修饰符对封装没有贡献,但对信息隐藏有贡献。

于 2012-12-17T11:29:27.240 回答
1
class NoEncapsulationNoInformationHiding { 
    public List widths = new ArrayList();
}

class EncapsulationNoInformationHiding {
    private ArrayList widths = new ArrayList();

    public ArrayList getWidths() {
        return this.widths;
    }
}

class EncapsulationInformationHiding {
    private List widths = new ArrayList();

    public List getWidths() {
        return this.widths;
    }
}
  • 封装:组合事物,例如数据和对这些数据进行操作的过程(组成一个对象)。封装意味着隐藏对象的数据,因为任何过程都可以对公共数据进行操作。
  • 信息隐藏:抽象事物,例如对象的实现,即对象的数据,其过程的实现,以及其过程的参数和返回值的类。信息隐藏意味着封装,但反之则不然。

示例灵感来自威廉·安德伍德的.

于 2018-10-08T20:22:02.490 回答
0

要回答您的问题:

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

封装:封装是将数据和方法结合起来,允许公共方法访问内部数据。所以,是的,如果在您的班级中,您将变量 age 设为私有,您将实现封装

于 2012-12-17T11:36:00.517 回答
0

当您不实施信息隐藏、封装或任何它所称的事情时,就会发生这种情况。当你在某个角落的某个地方改变你认为独立的东西时,就会发生不好的事情。其次,当您想更改系统中使用的第三方库时,您会发现系统中到处都有引用,如果不重构整个事物就无法移动。例如,您想升级您的数据访问库版本(我想更新 ODP.net 版本时遇到了这个问题),您估计工作是想修改应该引用数据库的 DataAccess 类客户端库。但是您会发现每个业务类都为 DB 客户端库创建了一个引用。现在您必须更新 60 个程序集的引用而不是一个 :( 信息泄露

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

于 2019-02-12T08:11:41.177 回答
-1

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

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

于 2018-01-20T05:31:58.373 回答