封装与数据隐藏 – Java

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

Me:封装是一种隐藏客户端信息的机制。 这些信息可能是数据或实现或algorithm。 我们使用访问修饰符来实现这一点。

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

:ummmmm

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

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

但是封装有时候也和你的答案一样,实际上绑定数据和方法的其中一点就是隐藏实现。

我想比只使用方法和使所有字段私有更好的答案是:使用接口。 这样,对象上的操作纯粹是基于接口契约,而不是绑定到用于在内部实现契约的字段或帮助器方法。

封装

一般来说封装意味着捆绑类似的物品,就这么简单。

例如,在一个Student类中,我们将学生实例variables和行为/方法作用于这些实例variables@在一个地方。

为什么这很重要? 我们不希望我们的代码遍布在我们的代码库中。

如果说,我们需要做出改变,那么我们需要在所有的地方find变化(变化的)。 通过捆绑类似的项目,我们只是避免这种情况下,它也有助于使我们的捆绑代码更集中。

数据隐藏

它只是提供了一种保护来自外部世界的数据的方法。 这意味着什么,让我们说如果我公开我的实例variables,那么任何人都可以改变它的状态。 但是,如果我们将实例variables设置为private / protected,那么实际上我们正在限制外部实体对其进行更改。

比较/讨论

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

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

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

所以我的观点是所有与学生有关的行为/variables都放在一个黑盒子里 ,我们把它称为一个class级。 现在它到了class级的devise师什么是class级的要素应该隐藏起来,什么不应该被外界隐藏起来。

现在回到问题在Java中:我们正在使我们的variables是私有的,这意味着它们是受保护的类。如果我们希望我们的实例variables在整个包中都是可访问的,那么它们将受到包保护。 通过项目他们是公开的。 所以我的意思是隐藏数据,你需要某种容器,你将把数据放在容器中。

所以我觉得数据隐藏是不可能的,没有封装 。 您不能将数据放入某种forms的容器中,而无法隐藏数据。 我再次提醒你,我正在把这个放在面向对象的语言环境中。

但是, 封装是可能的,而不隐藏你的数据。 把所有的东西都公开,你可以看到这种影响。

封装 :以胶囊为例。 如果你打开它,它包含了很多的成分。 面向对象编程的封装也是这样的。 顾名思义“ 封装就是将所有的数据成员,属性和相应的方法封装(制作一个胶囊)在一个胶囊中。

你是怎么做的:比如说你做了一个叫“汽车”的class。 现在汽车有一个颜色价格和型号。 这些是属性,它有一个运行方法。 所以在这里,你已经封装了一个名为“汽车”的所有这些属性和方法。 当你创build一个像这样的汽车的实例

 Car myCar = new Car(); 

您可以使用myCarvariables来访问Car的所有属性。

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

我讨厌这样做,但从维基百科 :

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

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

你的解释更符合第一个观点,面试官正在寻找第二个问题。

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

不过,我想了一下,下面是我相信可能是我试图回答这个问题。

使用访问修饰符

在Java中,封装是通过使用可访问性修饰符(即public,protected,private等)来隐藏细节来实现的。 通过这些可访问性级别,您可以控制隐藏信息的级别。 级别越低,发生的变化就越昂贵,并且类与其他依赖类(即用户类,子类)耦合得越多。

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

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

到目前为止,封装看起来完全依赖于编程语言的能力来隐藏细节,因此,如果没有访问修饰符就无法实现封装了,对吧?

没有访问修饰符

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

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

对我来说,面试问题似乎是要将封装评估为一个更广泛的概念,一个取决于非常明确的抽象的定义,而不仅仅是访问修饰符等语言特征的副产品。

抽象的作用

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

例如,在汽车概念的抽象层面上考虑。 一辆汽车内部实施起来很复杂。 他们有几个子系统,如传输系统,rest系统,燃料系统等。

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

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

想想汽车没有液压方向系统的时间。 有一天,汽车制造商发明了它,并决定把它从那里放进汽车里。 不过,这并没有改变用户与之交互的方式。 用户至多在方向系统的使用方面经历了改进。 像这样的变化是可能的,因为汽车的内部实施是封装的。

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

现在,认为汽车制造商决定把汽油盖放在汽车下面,而不是放在汽车的一侧。 你去买这些新车中的一辆,当你用完汽油时,你去加油站,而你没有find加油盖。 突然间,你意识到是在汽车下方,但你不能用气泵软pipe达到它。 现在,我们已经打破了公共接口契约,因此,整个世界都打破了,因为事情没有按照预期的方式运行,所以崩溃了。 像这样的变化将花费数百万美元。 我们需要改变世界上所有的加油泵。 当我们打破封装,我们必须付出代价。

所以,正如你所看到的,封装的目标是最大限度地减less相互依赖并促进变化 。 通过最大限度地减less实现细节的暴露,可以最大化封装。 一个类的状态只能通过其公共接口来访问。

封装美是在不影响用户的情况下改变事物的力量

我们可以说,这个最终的目标取决于精心的计划和devise。 在Java中,访问修饰符是将这些想法变为现实的一种方式,但在不存在此function的语言中,也可以实现封装。

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

例如 :一辆汽车。 它将方向盘,轮胎,发动机和所有相关材料保存在一个名为Car集体实体中。

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


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

例如 :当我们在汽车上踩刹车或踩油门时,我们不知道现场发生了什么事情( 如何提高速度或者如何将刹车装入轮胎)。 我们所知道的是我们有刹车和加速器来执行预期的结果。

在编程时,这是在访问修饰符的帮助下完成的。 私人会员不能从课外访问 ,只有public会员才能访问。 私人成员只能从class级成员那里获得,从而为私人成员提供从class级外直接评估的安全性

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

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

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

信息隐藏隐藏了一个对象如何在抽象API的背后实现其function。 它允许我们通过忽略与手头任务无关的更低层次的细节来处理更高的抽象。 devise层面的抽象可以用来实现数据隐藏。

最简单的封装定义是“将数据和代码操作成一个单元”,这样外部世界不能直接访问数据。

在结构语言如c数据在块的开始处声明并直接使用,公开访问(任何tom,dick和harry都可以访问数据)。 数据隐藏是一个概念,可以直接和公开地限制任何汤姆·迪克和哈里的数据访问。
封装是实现数据隐藏的途径之一。 通过将数据和函数放在一起(封装)来实现数据隐藏。

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

获得者和安装者如何工作?

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

  1. 低耦合(通过信息隐藏确保)
  2. 高凝聚力

封装:封装是OOPS的一个支柱,也是数据隐藏和抽象这两个术语的超集。 (数据隐藏,术语是指数据只能存储在variables中,为了隐藏外部数据,我们使用数据隐藏的概念Public,Private,Protected这三个访问修饰符提供给我们进行数据隐藏。受限于包。受保护的仅限于inheritance类。)**私有variables只能在类内部访问,这意味着如果存在内部类,那么也可以直接调用私有variables。 只有静态内部类可以调用静态variables。

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

**完成软件包,即将对象私有化,并将setter和getter中的逻辑实现称为ENCAPSULATION。

  1. 封装是将数据(字段)和行为(方法)捆绑在一起的类。
  2. 现在,您必须使用数据隐藏的访问修饰符(private / protected / public或default)来提供对数据的访问控制。 它保护您不想提供访问权限的外部世界的数据。
  3. 另外,为了隐藏操作的复杂性,你必须使用接口来实现抽象。

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

java是完全封装的元素

数据隐藏意味着将数据variables声明为私有的,以防止未经授权的访问,但是如果你正在给一些公共的setter和getter方法进行validation。

通过隐藏其从外部类成员的直接访问中获得的数据来定义类的过程,并且通过适当的validation仅通过可公开访问的setter和getter方法来提供访问,这称为封装(Encapsulation)。

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

封装=数据隐藏+抽象

数据隐藏意味着我们正在为class级内的数据提供安全性。

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

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

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

学生类被封装。

封装=数据隐藏+抽象