当前位置: 首页 > 知识库问答 >
问题:

Java封装[重复]

姬弘文
2023-03-14

我们总是说,如果我们简单地定义变量< code>private并定义getters setters来访问这些变量,那么数据就会被封装。我的问题是,如果我们可以通过getters和setters访问变量(数据),那么数据是如何隐藏或安全的呢?

我在谷歌上搜索了很多解释,但我什么也没找到。每个人都刚刚在他们的博客和帖子中说这是一种数据隐藏技术,但它还没有被解释/详细说明。

共有3个答案

郭单鹗
2023-03-14

数据是安全的,因为您可以在getter/setter中执行额外的逻辑,并且无法更改变量的值。想象一下,您的代码不适用于空变量,因此在您的setter中,您可以检查空值并分配一个默认值!=null。因此,无论是否有人尝试将您的变量设置为null,您的代码仍在工作。

席银龙
2023-03-14

我理解你的问题是,尽管我们将变量声明为私有,因为这些变量可以使用getters和setter访问,但它们不是私有的。因此,这样做的意义是什么?

好吧,在使用 getter 和 setters 时,您可以限制对私有变量的访问。

private int x;

public int getInt(String password){
 if(password.equals("RealPassword")){
   return x;
  }
}

二传手也是如此。

夏侯博
2023-03-14

封装不仅仅是为类定义访问器和赋值函数方法。它是面向对象编程的一个更广泛的概念,包括最小化类之间的相互依赖关系,并且通常通过信息隐藏来实现。

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

在像Java这样的面向对象的编程语言中,通过使用可访问性修饰符(公共,受保护,私有,加上没有修饰符(意味着包私有)隐藏细节来实现封装。通过这些级别的可访问性,您可以控制封装级别,该级别的限制越少,发生更改时的代价就越高,并且该类与其他依赖类(即用户类和子类)的耦合程度就越高。

因此,我们的目标不是隐藏数据本身,而是隐藏如何操作这些数据的实现细节。

这个想法是提供一个公共接口,您可以通过它访问这些数据。您可以稍后更改数据的内部表示,而不会损害类的公共接口。相反,通过公开数据本身,您会损害封装,从而损害在不影响其用户的情况下更改操作数据的方式的能力。您创建了对数据本身的依赖,而不是对类的公共接口的依赖。当“更改”最终找到你时,您将为麻烦创造一个完美的鸡尾酒。

您可能希望封装对字段的访问有几个原因。Joshua Bloch在他的《有效Java》一书的第14项:最小化类和成员的可访问性中提到了几个令人信服的原因,我在这里引用:

  • 您可以限制可存储在字段中的值(即性别必须为F或M)
  • 您可以在修改字段时采取操作(触发事件、验证等)
  • 您可以通过同步该方法来提供线程安全性
  • 您可以切换到新的数据表示形式(即计算字段、不同的数据类型)

然而,封装不仅仅是隐藏字段。在Java中,你可以隐藏整个类,这样就隐藏了整个API的实现细节。例如,在< code>Arrays.asList()方法中。它返回一个< code>List实现,但是您并不关心哪个实现,只要它满足< code>List接口,对吗?。将来可以更改实现,而不会影响该方法的用户。

现在,在我看来,要理解封装,首先必须理解抽象。

例如,在汽车概念的抽象层次上思考。汽车的内部实现很复杂。它们有几个子系统,像传动系统、刹车系统、燃料系统等。

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

然而,很少有人知道所有这些特性是如何实现的细节。想想汽车没有液压方向系统的时代。有一天,汽车制造商发明了它,他们决定把它安装在汽车上。然而,这并没有改变用户与他们互动的方式。最多,用户在使用定向系统方面有所改进。像这样的改变是可能的,因为car的内部实现是封装的。可以安全地进行更改,而不会影响其公共接口。

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

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

我真的建议你阅读Alan Snyder的一篇论文,名为《面向对象编程语言中的封装和继承》。这个链接指向ACM的原始论文,但我非常确定你能够通过Google找到PDF副本。

 类似资料:
  • 我实现了一个名为mobile eCall的类。我从这个类中创建了几个对象,并用来自XML的值填充该对象的String变量,该XML具有针对特定人员的多个mobile eCall。我需要对这个人发出的所有呼叫进行分组和计数(例如,国内呼叫:11分钟;国际呼叫:15分钟;数据:20 MB) 因此,我在类中实现了几个公共方法来检查调用的类型,以返回true或false。在主类中,我调用了这些方法来检查它

  • 上一小节中,我们已经对类和对象有了一个基本的认识。不止于 Java,在各个面向对象语言的书籍资料中,都会提到面向对象的三大特征:封装、继承、多态。本小节我们就从封装开始,探讨面向对象的特征。本小节我们将学习什么是封装、为什么需要封装,最后也会以一个 NBA 球员类的案例来实现封装。 1. 概念和特点 类的基本作用就是封装代码。封装将类的一些特征和行为隐藏在类内部,不允许类外部直接访问。 封装可以被

  • 封装将类的某些信息隐藏在类内部,不允许外部程序直接访问,只能通过该类提供的方法来实现对隐藏信息的操作和访问。例如:一台计算机内部极其复杂,有主板、CPU、硬盘和内存, 而一般用户不需要了解它的内部细节,不需要知道主板的型号、CPU 主频、硬盘和内存的大小,于是计算机制造商将用机箱把计算机封装起来,对外提供了一些接口,如鼠标、键盘和显示器等,这样当用户使用计算机就非常方便。 封装的特点: 只能通过规

  • 6.6. 封装 一个对象的变量或者方法如果对调用方是不可见的话,一般就被定义为“封装”。封装有时候也被叫做信息隐藏,同时也是面向对象编程最关键的一个方面。 Go语言只有一种控制可见性的手段:大写首字母的标识符会从定义它们的包中被导出,小写字母的则不会。这种限制包内成员的方式同样适用于struct或者一个类型的方法。因而如果我们想要封装一个对象,我们必须将其定义为一个struct。 这也就是前面的小

  • prototype对象 构造函数的缺点 prototype属性的作用 原型链 constructor属性 Object.getPrototypeOf方法 Object.create方法 isPrototypeOf方法 prototype对象 构造函数的缺点 JavaScript通过构造函数生成新对象,因此构造函数可以视为对象的模板。实例对象的属性和方法,可以定义在构造函数内部。 function

  • 根据Geeksforgeks的说法。java封装中的组织/封装=数据隐藏抽象?如果是,那么我可以看到数据隐藏,但抽象在哪里? 有些人将此作为封装的示例 有些人说这不是一个封装的例子。参考:https://www.youtube.com/watch?v=tjyZWqJkNpc(在这个视频中教学的人在java上真的很好,很难相信他会错) 那么什么是真正的封装呢? 数据隐藏抽象 将变量和方法分组到单个单