封装与数据隐藏 - Java

时间:2012-08-17 21:31:38

标签: java oop encapsulation software-design data-hiding

  

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

     

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

     

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

     

:uummmm

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

19 个答案:

答案 0 :(得分:38)

更一般地说,封装简单地指的是将数据(例如对象)与对该数据的操作捆绑在一起。因此,您有一个封装数据的类 - fields - 以及用于操作该数据的方法

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

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

答案 1 :(得分:17)

封装

一般来说,封装意味着捆绑类似的项目,就像那样简单。

例如,参加一个Student课程,我们将让学生实例变量和行为/方法在一个地方作用于这些实例变量。

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

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

数据隐藏

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

比较/讨论

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

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

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

所以我的观点是所有与学生相关的行为/变量都放在黑盒子中,我们称之为一个类。现在,对于类的设计者来说,应该隐藏类的元素,以及不应该从外部世界隐藏的内容。

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

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

但是可以在不隐藏数据的情况下使用封装。把所有事情都公开,你可以看到影响。

答案 2 :(得分:8)

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

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

Car myCar = new Car();

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

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

答案 3 :(得分:3)

我讨厌这样做,但是来自Wikipedia

  

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

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

你的解释更像是第一个概念,面试官正在寻找第二个问题。

答案 4 :(得分:3)

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

示例:一辆车。它将方向盘,轮胎,引擎和所有相关的东西保存在一个称为Car的集体实体中。

在编程语言中,使用实现封装。类包含one single entity中用于执行特定任务的所有属性和相关方法。

数据隐藏是指隐藏用户中不重要的详细信息,并仅向他显示相关数据。

示例:当我们在车内按下制动器或加速器时,我们不知道幕后发生了什么( 它增加了它速度或如何将刹车应用到轮胎中)。我们所知道的是,我们有制动器和加速器来实现预期的结果。

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

答案 5 :(得分:2)

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

不过,我还是考虑了一下,我认为以下是我试图回答这个问题的原因。

使用访问修饰符

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

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

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

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

没有访问修饰符

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

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

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

抽象的作用

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

例如,考虑一下汽车概念的抽象层次。汽车内部实施复杂。他们有几个子系统,如传输系统,中断系统,燃料系统等。

然而,我们已经简化了它的抽象,我们通过它们的抽象的公共接口与世界上的所有汽车进行交互。我们知道所有的汽车都有一个方向盘,通过它我们控制方向,他们有一个踏板,当你按下它时你加速汽车和控制速度,另一个当你按下它你让它停止,你有一个变速杆如果你向前走,你可以控制这些功能构成了汽车抽象的公共接口。早上你可以驾驶一辆轿车然后下车并在下午驾驶一辆SUV,好像它是一样的。

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

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

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

现在,我认为汽车制造商决定将燃油盖放在汽车下方,而不是在其中一侧。你去购买这些新车中的一辆,当你用完汽油时,你会去加油站,而你却找不到加油盖。突然你意识到是在汽车下面,但你无法用气泵软管到达它。现在,我们打破了公共接口合同,因此,整个世界都破裂了,它因为事情没有按照预期的方式运转而崩溃。这样的改变会花费数百万美元。我们需要改变世界上所有的气泵。当我们打破封装时,我们必须付出代价。

因此,正如您所看到的,封装的目标是最小化相互依赖性并促进变更。您可以通过最小化实现细节的曝光来最大化封装。只能通过公共接口访问类的状态。

封装的美妙之处在于能够在不影响用户的情况下改变事物

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

答案 6 :(得分:1)

抽象说,需要与对象进行交互。

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

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

答案 7 :(得分:1)

基本上,数据封装是一个过程,而数据隐藏是一种技术。 在封装中,数据可以是公共的或私有的,但在数据隐藏中,数据仅是私有的。因此,数据隐藏使用封装,但也使用不同的技术来保留仅允许授权访问的数据。 希望对您有帮助!

答案 8 :(得分:1)

From Wikipedia

  

封装封装是一种面向对象的编程概念   将数据和处理数据的功能绑定在一起,   并确保免受外界干扰和滥用。数据   封装导致了重要的面向对象的数据隐藏概念。

     

如果一个类不允许调用代码访问内部对象数据   并且仅允许通过方法进行访问,这是一种很强的   抽象或信息隐藏称为封装。一些   语言(例如Java)让类强制执行访问限制   明确地表示,例如用私有表示内部数据   关键字和指定方法,供代码之外的代码使用   使用public关键字的类。方法也可以公开设计,   私有或中间级别,例如受保护(允许访问)   来自相同的类及其子类,但不是来自不同对象的对象   类)。在其他语言(如Python)中,这仅由   约定(例如,私有方法的名称可以以   下划线)。封装可防止外部代码被入侵   与物体的内部运作有关。这有利于   代码重构,例如允许类的作者   更改该类的对象如何在内部表示其数据   无需更改任何外部代码(只要“ public”方法调用   以相同的方式工作)。它还鼓励程序员放所有代码   与同一类中的一组特定数据有关,   组织它以便其他程序员容易理解。   封装是一种鼓励去耦的技术。

答案 9 :(得分:1)

  

数据隐藏意味着我们为类中的数据提供安全保障。

     

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

     

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

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

学生班是封装的。

  

封装=数据隐藏+抽象

答案 10 :(得分:1)

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

封装=数据隐藏+抽象

答案 11 :(得分:1)

我看到它的方式,封装绑定数据方法的概念引用到单位称为 class 。但是,有 两个主要标准 来绑定数据和方法。其中一个是信息隐藏,而不是唯一的信息隐藏。完全简洁我会说两个主要标准是

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

答案 12 :(得分:1)

通过隐藏来自外部类成员的直接访问来定义类的过程,并通过适当的验证仅通过公共可访问的setter和getter方法提供访问,称为Encapsulation。

答案 13 :(得分:1)

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

Class是java中的完全封装元素

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

答案 14 :(得分:1)

  1. ENCAPSULATION是将数据(字段)和行为(方法)捆绑在一起。
  2. 现在,您必须使用访问修饰符(private / protected / public或default)提供对数据的访问控制,即DATA HIDING。 它可以保护您不希望提供访问权限的外部数据。
  3. 此外,为了隐藏操作的复杂性,您必须使用接口才能实现ABSTRACTION。

答案 15 :(得分:1)

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

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

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

答案 16 :(得分:1)

最简单的封装定义是“将数据绑定到一个单元中的数据和代码”,这样外部世界就无法直接访问数据。

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

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

How do getters and setters work?

答案 17 :(得分:1)

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

<强>封装 确保对象的行为只能通过其API进行影响。 它让我们可以控制对一个对象的更改会对其他部分产生多大影响 系统通过确保之间没有意外的依赖关系 不相关的components.Access修饰符可以用来实现Encapsulation。

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

答案 18 :(得分:1)

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