59

采访者:什么是封装,你是如何在 Java 中实现它的?

我: 封装是一种向客户端隐藏信息的机制。该信息可以是数据或实现或算法。我们使用访问修饰符来实现这一点。

采访者:这是数据隐藏。我们如何在 Java 中实现封装?

:嗯嗯

具体问题:除了“访问修饰符”之外,在 Java 中实现封装的方法是什么?

4

19 回答 19

44

更一般地,封装只是指将数据(例如对象的数据)与对该数据的操作捆绑在一起。所以你有一个封装数据的类 -字段- 以及操作该数据的方法

但是封装有时也以与您的答案相同的方式使用,实际上,捆绑数据和方法的要点之一是隐藏实现。

我认为比仅使用方法并将所有字段设为私有更好的答案是:使用接口。这样,对对象的操作完全基于接口契约,并且与用于在内部实现该契约的字段或辅助方法无关。

于 2012-08-17T21:35:08.303 回答
24

封装

一般来说,封装意味着捆绑相似的项目,就这么简单。

例如,上一Student堂课,我们将让学生实例变量和作用于这些实例变量的行为/方法@一个地方。

为什么它很重要?我们不希望我们的代码分散在我们的代码库中。

如果假设我们需要进行更改,那么我们需要在所有地方找到(更改的)变体。通过捆绑类似的项目,我们只是避免了这种情况,它还有助于使我们的捆绑代码更加集中。

数据隐藏

它只是提供了一种保护您的数据免受外界影响的方法。这意味着,假设我公开了我的实例变量,那么任何人都可以更改它的状态。但是,如果我们将实例变量设为私有/受保护,那么实际上我们是在限制外部实体对其进行更改。

比较/讨论

现在问题出现了,我们在哪些方面保护我们的变量?

同样,我们需要了解封装只是我们需要放置类似项目的容器。

它对外界就像一个黑盒子。外部世界(我的意思是说客户/消费者:使用我们的Student课程)不知道课程的内部细节/实施细节,Student实际上他们不应该关心课程的内部细节/实施细节。他们只想要一些方法/API,以便他们可以在他们的客户端应用程序中使用它们。

所以我的观点是所有与学生相关的行为/变量都放在一个黑盒子里,我们称之为一个班级。现在由类的设计者决定哪些类的元素应该隐藏,哪些不应该对外界隐藏。

现在回到Java中的问题:我们将变量设为私有,这意味着它们是受类保护的。如果我们希望我们的实例变量可以在整个包中访问,那么它们是包保护的。通过整个项目,它们是公开的。所以我的意思是隐藏你需要某种容器的数据,你将在其中放置数据并相对于容器隐藏。

所以我觉得没有Encapsulation数据隐藏是不可能的。如果不将数据放入某种形式的容器中,就无法隐藏数据。我再次提醒您,我将它放在面向对象的语言上下文中。

但是,可以在不隐藏数据的情况下进行封装。把所有的事情都公开,你就能看到效果。

于 2014-11-20T09:39:33.947 回答
10

封装:以胶囊为例。打开一看,里面有很多成分。面向对象编程的封装也是如此。顾名思义,“封装意味着将所有数据成员、属性和相应的方法封装(封装)在一个单独的封装中。

你是怎么做的:假设你创建了一个名为“Car”的类。现在汽车有颜色价格和型号。这些是属性,它有一个 run 方法。所以在这里你已经封装了一个名为“Car”的车辆的所有这些属性和方法。当您像这样创建汽车实例时

Car myCar = new Car();

您可以使用 myCar 变量访问 Car 的所有属性。

数据隐藏”:在 Java 中使用访问修饰符控制数据隐藏。要访问您使用ACCESSORS的数据成员,同时使用“ Mutators ”修改数据。Java 本身不提供访问器和修改器,您自己创建它们(getter 和 setter)。虽然 C# 提供了这样做的属性。

于 2015-05-14T09:55:41.540 回答
7

我讨厌这样做,但是,来自维基百科

在编程语言中,封装用于指代两个相关但不同的概念之一,有时指的是它们的组合:

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

您的解释更符合第一个概念,面试官正在寻找第二个概念。

于 2012-08-17T21:49:01.767 回答
3

数据封装是指将所有相关属性和方法保存在一个实体中的机制。

示例:汽车。它将方向盘、轮胎、发动机和所有相关的东西整合到一个称为Car.

在编程语言中,封装是通过来实现的。one single entity一个类包含旨在执行特定任务的所有属性和相关方法。


数据隐藏是指对用户隐藏不重要的细节,只向他显示相关数据。

示例:当我们在汽车中踩刹车或加速时,我们不知道幕后发生了什么(它如何提高速度或如何将刹车应用到轮胎上)。我们所知道的是,我们有刹车和加速器来执行预期的结果。

在编程中,这是在访问修饰符的帮助下完成的。私有成员不能从类外部public访问,用户只能访问成员。私有成员只能从类的成员中访问,从而为私有成员提供安全性,以便从类外部直接评估。

于 2017-05-26T13:14:20.657 回答
3

数据隐藏意味着我们为类内的数据提供安全性。

抽象意味着通过定义成员函数来隐藏代码。

封装是抽象和数据隐藏的结合,意味着我们正在包装数据和与该数据相关的代码。对于前豆类

    class student {
private int age;  // Data Hiding 
public setAge(){} // Abstraction 
public getAge(){} // Abstraction 
}

学生类被封装。

封装 = 数据隐藏 + 抽象

于 2017-08-25T09:33:44.850 回答
2

这个问题似乎具有误导性,我怀疑除了面试官之外的任何人都可能回答这个问题,而且他/她的回答很可能是错误的。最重要的是,尚不清楚该问题应该评估或发现什么。

尽管如此,我还是考虑了一下,以下是我认为可能是我回答这个问题的尝试。

使用访问修饰符

在Java 中,封装是通过使用可访问性修饰符(即public、protected、private 等)隐藏细节来实现的。通过这些级别的可访问性,您可以控制信息隐藏的级别。级别的限制越少,更改发生的代价就越大,并且类与其他依赖类(即用户类、子类)的耦合程度越高。

显然,封装不仅仅是隐藏状态。在 Java 中,您可以隐藏整个类和接口及其状态和行为,从而隐藏整个 API 的实现细节。

例如,方法Arrays.asList()返回一个List实现,但我们不关心哪个实现,只要它满足List公共接口,对吧?将来可以更改实现而不影响我们,方法的用户,但实际的实现对我们是隐藏的。

到目前为止,似乎封装完全取决于编程语言隐藏细节的能力,因此,如果没有访问修饰符,它就无法实现,对吧?

没有访问修饰符

但是,像 Python 这样的语言在没有访问修饰符的情况下是如何实现封装的呢?Python 中的一切都是公开的?这是否意味着封装是不可能的?

如果按照惯例,我们定义了组件的公共接口,然后只通过它们的公共接口访问对象的状态和行为呢?显然,为此,我们需要清楚地了解问题域中的抽象以及我们的用户应该如何使用这些抽象。

在我看来,面试问题似乎旨在将封装评估为更广泛的概念,一个取决于非常清晰抽象的定义,而不仅仅是访问修饰符等语言功能的副产品。

抽象的作用

这就是为什么,在我看来,要真正理解封装,首先必须理解抽象。

例如,考虑汽车概念的抽象级别。汽车的内部实现很复杂。它们有几个子系统,如传动系统、制动系统、燃油系统等。

然而,我们已经简化了它的抽象,我们通过它们抽象的公共接口与世界上所有的汽车进行交互。我们知道所有的汽车都有一个方向盘,我们可以通过它控制方向,它们有一个踏板,当你按下它时,你可以加速汽车并控制速度,还有一个当你按下它时,它就会停下来,还有一个变速杆让您控制是否前进或后退。这些特性构成了汽车抽象的公共接口。早上你可以开一辆轿车,然后下车,下午开一辆 SUV,就好像它是同一件事一样。

并不是说你不能打开引擎盖看看它是如何工作的。然而,我们中很少有人知道所有这些底层功能是如何在引擎盖下实现的细节,而事实是我们不需要知道驾驶汽车的细节。所有这些东西都封装在汽车抽象之下。我们只需要知道抽象的公共接口。

想想汽车没有液压方向系统的时代。有一天,汽车制造商发明了它,他们决定从那时起将其放入汽车中。尽管如此,这并没有改变用户与他们交互的方式。最多,用户体验到使用定向系统的改进。像这样的改变是可能的,因为汽车的内部实现被封装了。

这清楚地表明,通过隐藏定向系统的实现细节,他们可以安全地更改它,而不会影响汽车的公共界面,相应地,也不会影响用户与其交互的方式。

现在,想想汽车制造商决定把油箱盖放在汽车下面,而不是放在汽车的一侧。你去买一辆这样的新车,当你用完油时,你去加油站,却找不到油箱盖。突然你意识到在汽车下方,但你无法用气泵软管到达它。现在,我们已经破坏了公共接口契约,因此,整个世界都崩溃了,它分崩离析,因为事情没有按照预期的方式工作。像这样的改变将花费数百万美元。我们需要更换世界上所有的气泵。当我们打破封装时,我们必须付出代价。

因此,如您所见,封装的目标是最大限度地减少相互依赖并促进变化。您可以通过最小化实现细节的暴露来最大化封装。类的状态只能通过其公共接口访问。

封装的美妙之处在于改变事物而不影响其用户的力量

我们可以说,这个最终目标取决于仔细的规划和设计。在 Java 中,访问修饰符是一种将这些想法变为现实的方法,但在不存在此功能的语言中,同样可以实现封装。

于 2012-09-01T15:19:33.837 回答
2

在我看来,封装是指将数据和方法绑定到称为的单个单元的想法。然而,绑定数据和方法有两个主要标准。其中之一是信息隐藏,但不是唯一的。为了完全简洁,我想说两个主要标准是

  1. 低耦合(通过信息隐藏确保)
  2. 高凝聚力
于 2017-01-20T12:42:54.213 回答
1

在类中,属性和行为放在一起。封装意味着,当你创建一个类时,这本身就意味着你实现了封装原则。因为数据和行为被封装到类中。所以数据隐藏是术语的主要部分——封装。这意味着对象的访问点。

于 2013-04-09T22:09:46.840 回答
1

我看到很多讨论已经完成,只是为了简化我的理解:

封装 确保对象的行为只能通过其 API 受到影响。通过确保不相关的组件之间没有意外的依赖关系,我们可以控制对一个对象的更改对系统其他部分的影响程度。访问修饰符可以用来实现封装。

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

于 2013-10-29T09:32:08.830 回答
1

封装最简单的定义是“将数据和操作数据的代码绑定到一个单元中”,使得数据不能被外界直接访问。

在像c这样的结构语言中,数据在块的开头声明并直接使用,公开访问(任何tom,dick和harry都可以访问数据)。数据隐藏是一个概念,它直接和公开地限制任何汤姆迪克和哈利的数据访问。
封装是实现数据隐藏的方法之一。您通过将数据和功能放在一起(封装)来实现数据隐藏。

如何在 JAVA 中实现,请参阅 JAVA 中的任何 getter()、setter() 函数示例。检查这个

getter 和 setter 是如何工作的?

于 2015-08-07T13:04:18.597 回答
1

封装:封装是OOPS的支柱之一,也是其他两个术语,数据隐藏和抽象的超集。(数据隐藏,顾名思义。数据只能存储在变量中。为了向外部世界隐藏数据,我们使用数据隐藏概念。公共、私有、受保护这三个访问修饰符提供给我们用于数据隐藏。默认为仅限于包。受保护仅限于继承类。)**私有变量只能在类内部访问,这意味着如果有内部类,也可以直接调用私有变量。只有静态内部类可以调用静态变量。

现在来抽象(意思是无形的)。抽象也被认为是对用户隐藏实现并仅提供最终结果的过程。示例:我们有一个具有“重量”属性的人员类。这个属性非常棘手,因为我们不能接受一个人的体重小于 0。我们也不能接受超过 500 公斤。所以隐藏这些的实现将在 setter 方法中。这个隐藏实现细节的东西是抽象。

** 完整的包,即使对象私有化并在 setter 和 getter 中实现逻辑称为 ENCAPSULATION。

于 2016-01-04T16:27:13.140 回答
1
  1. 封装是将数据(字段)和行为(方法)捆绑在类中。
  2. 现在,您必须使用访问修饰符(私有/受保护/公共或默认)提供对数据的访问控制,即 DATA HIDING。它可以保护您不想提供访问权限的外部世界的数据。
  3. 此外,为了隐藏操作的复杂性,您必须使用接口来实现抽象。
于 2016-03-22T08:21:09.670 回答
1

封装意味着将数据成员和方法(行为)绑定在一个单元中,并提供尽可能多的用户所需的信息,您可以说[封装=数据隐藏+抽象]。

类是java中完全封装的元素

数据隐藏意味着将数据变量声明为私有以防止未经授权的访问,但如果您提供一些公共的 setter 和 getter 方法进行验证。

于 2016-06-30T16:43:13.350 回答
1

通过隐藏其数据以防止外部类成员直接访问并仅通过适当的验证通过可公开访问的 setter 和 getter 方法提供访问来定义类的过程称为封装。

于 2016-11-26T14:01:56.543 回答
1

来自维基百科

封装 封装是一种面向对象的编程概念,它将数据和操作数据的函数绑定在一起,并确保两者免受外部干扰和误用。数据封装导致了数据隐藏这一重要的 OOP 概念。

如果一个类不允许调用代码访问内部对象数据而只允许通过方法访问,这是一种强抽象或信息隐藏形式,称为封装。某些语言(例如 Java)允许类显式地强制执行访问限制,例如使用 private 关键字表示内部数据,并使用 public 关键字指定旨在供类外部代码使用的方法。方法也可以设计为公共、私有或中间级别,例如受保护的(允许从同一类及其子类访问,但不允许从不同类的对象访问)。在其他语言(如 Python)中,这仅按约定强制执行(例如,私有方法的名称可能以下划线开头)。封装防止外部代码关注对象的内部工作。这有助于代码重构,例如允许类的作者更改该类的对象在内部表示其数据的方式,而无需更改任何外部代码(只要“公共”方法调用以相同的方式工作)。它还鼓励程序员将与特定数据集相关的所有代码放在同一个类中,这样可以将其组织起来以便其他程序员理解。封装是一种鼓励去耦的技术。方法调用的工作方式相同)。它还鼓励程序员将与特定数据集相关的所有代码放在同一个类中,这样可以将其组织起来以便其他程序员理解。封装是一种鼓励去耦的技术。方法调用的工作方式相同)。它还鼓励程序员将与特定数据集相关的所有代码放在同一个类中,这样可以将其组织起来以便其他程序员理解。封装是一种鼓励去耦的技术。

于 2018-06-28T20:15:51.983 回答
1

基本上数据封装是一个过程,而数据隐藏是一种技术。在封装中,数据可以是公共的或私有的,但在数据隐藏中,数据只是私有的。所以数据隐藏使用封装,但它也使用不同的技术来保持数据只允许授权访问。希望能帮助到你!

于 2018-07-02T15:22:11.100 回答
1

抽象表示需要与对象交互的内容。

封装意味着将对象的属性、状态和行为封装到称为类的单个逻辑单元中。

数据隐藏表示隐藏对象的内部实现意味着私有方法和属性,即用于维护其状态的对象。

于 2018-12-18T01:38:45.777 回答
0

将数据成员和相应的方法绑定到一个单元中的过程只不过是封装。

封装 = 数据隐藏 + 抽象

于 2017-08-14T07:39:25.150 回答