Java setter 和 getter?
大家都知道Java支持数据隐藏。
我去面试了。然后面试官问我Java是否支持使用private作为数据类型来隐藏数据。
他说,如果我们在该类中使用 setter 和 getter,那么通过使用这些 setter 和 getter,我们可以轻松获取私有数据。
那么这如何支持数据隐藏呢?
有可能他是想让我落入陷阱。但我无法回答这个问题。
对此我应该回复什么?
Everyone knows that Java supports data hiding.
I went for an interview. Then interviewer asked me that if Java supports data hiding by using private as datatype.
He said if we use setters and getters in that class then by using those setters and getters we can get that private data easily.
So how this is supporting data hiding here?
It may be possible that he was trying me catch me in trap. But I could not reply this.
What should I reply for this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
他认为,如果“数据隐藏”是 OOP 原则,那么我们不是通过 getter 和 setter 进行暴露来打破它吗?我认为他希望您阐明直接访问数据成员与通过 getter 或 setter 访问数据成员之间的原则差异。在前一种情况下,类的客户端可能会错误地处理数据,为其分配一个类设计者未设计类来处理的值(例如将学生的年龄设置为 500)。
在后者(使用设置器)中,类设计者对可以分配给数据的值施加了某些限制。在年龄示例中,setter 可能类似于:
假设不允许 3 岁以下和 100 岁以上的学生。因此,您仍然隐藏数据,但允许以与模块逻辑一致的方式操作它。
He was arguing that if "Data Hiding" is an OOP principle then aren't we breaking it by exposing via getters and setters. I think he wanted you to spell out the difference in principle between being able to access a data member directly vs. doing it via a getter or setter. In the former case a client of the class can mishandle the data, assign it a value that the class designer has not designed the class to handle (for example set the age of a student as 500).
In the latter (using a setter) the class designer has imposed certain restrictions on what values can be assigned to the data. In the age example the setter might be something like:
assuming that students of age below 3 and over 100 aren't allowed. So you are still hiding your data but allowing means to manipulate it in a way consistent with the logic of your module.
非常简单的示例:
类的版本 1 可以有这样的 getter。
版本 2 可以做到这一点
我们已经更改了类的实现方式,但类的客户端也不需要更改,因为数据隐藏在 getter 后面。
Very simple Example:
Version 1 of class could have getter like this.
Version 2 could do this
We've changed how the class is implemented, but clients of the class don't need to change as well, because the data is hidden behind a getter.
数据隐藏这个词不好,最好说是数据封装。在java中,对私有成员的访问是通过访问器和修改器(getter和setter)完成的,这都是关于隐藏和控制对成员的访问,以便您可以控制如何修改实例的内部状态。
我想如果你提到一些关于java反射/元数据的事情->您将获得奖励积分
Data hiding is bad term, better say data encapsulation. In java access to private members is done through accessors and mutators ( getter and setter), it is all about hiding and controlling access to your members so you can control how inner state of instance will be modified.
I think if you mention something about java reflection / metadata -> you will get bonus points
如果我们将类字段声明为
私有
,那么它们就会被隐藏。毫无疑问(我们忽略讨厌的反射技巧)。如果我们想让值可访问,我们提供访问方法(例如 getter/setter)。但不要求为所有字段提供 getter 和 setter 或根据字段命名(一般情况下)。
类内部(字段)被完全隐藏。
The class fields are hidden, if we declare them
private
. No doubt (we ignore nasty reflection tricks). If we want to make the values accessible, we provide access methods (getter/setter for example).But there is no requirement to provide getters and setters for all fields or to name them according to fields (in general).
The class internals (the fields) are perfectly hidden.
在这个简单的例子中,可以通过该类及其所有子类中的名称来访问 name 属性。如果您想从不相关的类设置
name
的值,则必须使用setName()
方法,例如您可以在其中应用一些验证。在这里您可以找到有关此特殊方法的任何信息。
请注意,如果修改器和访问器是
public
,则可以访问类的任何属性。这是 Java Bean 概念的关键点之一,几乎所有 Java 框架都与这个概念相关在某一点或另一点。In this simple case the name attribute can be accessed by its name in this class and in all its children. If you want to set the value of
name
from an unrelated class than you will have to use thesetName()
method where you can apply some validation for example.Here you can find any information you need about this special methods.
Be aware that any property of a class can be accessed if the mutators and accessors are
public
. This is one of the key points of the Java Bean concept and almost all java frameworks relate to this concept at one point or another.您所说的似乎是封装。基本上,getter 和 setter 允许您根据需要公开类变量并隐藏任何其他变量。 Getters 和 Setters 还允许您执行任何其他必要的步骤,例如验证。
Getter 和 Setter 本身可以具有不同的访问修饰符,因此您可以通过使用不同的访问修饰符将数据公开给某些类,但不能公开给其他类。
What you are talking about seems to be Encapsulation. Basically the getters and setters allow you to expose class variables as you like and hide any others. Getters and Setters also allow you to perform any other necessary steps such as validation.
Getters and Setters can have different access modifiers themselves, so you can expose data to certain classes but not others by using different access modifiers.
我敢打赌他正在等待您也会提到“不可变”类型。
PD。 private 不是类型,它是一个访问修饰符。
I bet he was waiting that you will refer to "immutable" types also.
PD. private is no type, it is an access modifier.
对“数据隐藏”的支持可以通过以下事实来解释:getter 和 setter 方法就像数据的网关。
仅按照惯例 - 准确地说是 JavaBeans 惯例 - 这是他们所期望的对以其命名的成员进行操作。他们可以做任何事情,而且它仍然是完全可编译且合法的java。
The support for "data hiding" can be explained by the fact that the getter and setter methods are like gateways to the data.
It is only by convention - the JavaBeans convention to be exact - that it is expected from them to operate on the member they are named after. They could do anything else and it would still be perfectly compilable and legal java.
也许,他的意思是封装作为信息隐藏。
Maybe, he mean Encapsulation as information hiding.
如果您制作 setter & getter 为公共/受保护/默认,那么您可以访问不同级别的私有成员。如果您将 setter 和 getter 设置为私有,那么数据实际上是隐藏的。但这最后一条路根本没有意义
If you make the setter & getter public/protected/default, then you could access the private members on different levels .. if you make setter&getter private then the data is really hidden. This last way to go makes no sense at all though
您可能会考虑以多种不同的方式实现 set/get 方法。
You may think about implement set/get methods in many different ways.
正如一些答案已经指出的那样,set/get 不必实际设置或返回实际成员。
例如,假设您有一个坐标类,其中对 (x, y) 进行 set/get 操作。内部实现可能基于极坐标:
并且 (x, y) 的获取/设置使用 sin 和 cos 进行一些坐标转换。
您可以随意将类的实现更改为任何其他坐标系,并且仍然将 (x, y) 的 set/get 保留为公共方法。
因此,总而言之,我对这个问题的回答是:类的公共接口可能提供 set/get,但实际的实现可以(并且应该)通过将所有成员设为私有(或受保护)来隐藏。因此我们可以说对私有数据进行公共设置/获取是“实现隐藏”而不是数据隐藏。
As some answers already pointed out, set/get don't have to actually set or return actual members.
For example, let's say you have a Coordinate class with set/get for (x, y). The inner implementation might be based on polar coordinates:
and the get/set for (x, y) do some coordinate transformation with sin and cos.
You could change the implementation of the class to any other system of coordinate at will and still just keep the set/get for (x, y) as public methods.
So, to sum up, my answer to the question would be: the public interface of a class might provide set/get, but the actual implementation can (and should) be hidden by making all members private (or protected). So we could say that having public set/get on private data is "implementation hiding" rather than data hiding.
第一次 oops 学习者经常将数据隐藏和封装误认为是安全性。重要的是要了解数据隐藏和封装与安全性无关。
这些概念的存在是为了确保从类 B 继承类 A(类 B 扩展 A)不会继承“封装”成员。
我希望这能澄清你的困惑,并激励你更多地阅读和学习。你的问题对于 OOPS 概念来说是非常基本的。而且面试官并不是想逼迫你,而是问你关于 OOPS 的非常基本的问题。努力学习!!!
Data Hiding and Encapsulation are frequently mistaken for security by first time oops learners. Its important to understand that data hiding and encapsulation have nothing to do with security.
These concepts exist to ensure that inheritance of a class A, from class B (class B extends A) does not inherit the "encapsulated" members.
I hope this kinda clarifies your confusion, and also motivates you to read and study more. Your question is very basic to the OOPS concepts. And the interviewer is not trying to corner, you but ask you very basic questions on OOPS. Study hard!!!