简体   繁体   English

Java setter和getter?

[英]Java setter and getter?

Everyone knows that Java supports data hiding. 每个人都知道Java支持数据隐藏。

I went for an interview. 我去面试了。 Then interviewer asked me that if Java supports data hiding by using private as datatype. 然后面试官问我Java是否支持通过使用private作为数据类型来隐藏数据。

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. 他说,如果我们在该类中使用setter和getter,那么通过使用这些setter和getter,我们可以轻松获取私有数据。

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? 我对此应该回答什么?

He was arguing that if "Data Hiding" is an OOP principle then aren't we breaking it by exposing via getters and setters. 他在争辩说,如果“数据隐藏”是OOP原则,那么我们不是通过通过getter和setter进行公开来破坏它。 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. 我认为他希望您阐明在原理上能够直接访问数据成员与通过getter或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). 在前一种情况下,班级的客户可能会处理错误的数据,为其分配一个班级设计者尚未设计要处理的班级的值(例如,将学生的年龄设置为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: 在年龄示例中,二传手可能类似于:

void setAge(int age) {
if(age<3 || age>100) 
  return;
this.age=age;
}

assuming that students of age below 3 and over 100 aren't allowed. 假设不允许3岁以下且100岁以上的学生。 So you are still hiding your data but allowing means to manipulate it in a way consistent with the logic of your module. 因此,您仍在隐藏数据,但允许以与模块逻辑一致的方式操纵数据。

Very simple Example: 很简单的例子:

Version 1 of class could have getter like this. 该类的版本1可能会有这样的getter。

public int getTotal() {
   return total_;
}

Version 2 could do this 版本2可以做到这一点

public int getTotal() {
  return a + b;
}

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. 我们已经更改了类的实现方式,但是该类的客户端也不需要更改,因为数据隐藏在吸气剂的后面。

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. 在Java中,通过访问器和更改器(getter和setter)完成对私有成员的访问,这全都在于隐藏和控制对成员的访问,以便您可以控制实例内部状态的修改方式。

I think if you mention something about java reflection / metadata -> you will get bonus points 我认为如果您提到有关Java反射/元数据的内容->您将获得加分

The class fields are hidden, if we declare them private . 如果我们将class字段声明为private ,则它们是隐藏的。 No doubt (we ignore nasty reflection tricks). 毫无疑问(我们忽略了讨厌的反射技巧)。 If we want to make the values accessible, we provide access methods (getter/setter for example). 如果要使这些可访问,则可以提供访问方法(例如,getter / setter)。

But there is no requirement to provide getters and setters for all fields or to name them according to fields (in general). 但是不需要为所有字段提供getter和setter或根据字段(通常)来命名它们。

The class internals (the fields) are perfectly hidden. 类内部(字段)完全隐藏。

protected String name;

public void setName(String newName){
    if(newName.length() > 5) this.name = newName
}

public String getName(){
    return this.name;
}

In this simple case the name attribute can be accessed by its name in this class and in all its children. 在这种简单情况下,可以通过其名称在此类及其所有子级中访问name属性。 If you want to set the value of name from an unrelated class than you will have to use the setName() method where you can apply some validation for example. 如果要从不相关的类中设置name的值,则必须使用setName()方法,例如,可以在其中应用一些验证。

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 . 请注意,如果更改器和访问器是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. 这是Java Bean概念的关键点之一,几乎所有的Java框架都在某一点或另一点与此概念相关。

The support for "data hiding" can be explained by the fact that the getter and setter methods are like gateways to the data. 可以通过以下事实来解释对“数据隐藏”的支持:getter和setter方法就像通往数据的网关。

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. 只有按照约定 (准确地说是JavaBeans约定) ,它们才可以在以其命名的成员上进行操作。 They could do anything else and it would still be perfectly compilable and legal java. 他们可以做其他任何事情,并且仍然是完全可编译且合法的Java。

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. 基本上,getter和setter允许您根据需要公开类变量并隐藏其他变量。 Getters and Setters also allow you to perform any other necessary steps such as validation. Getter和Setters还允许您执行任何其他必要的步骤,例如验证。

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. Getter和Setter本身可以具有不同的访问修饰符,因此可以通过使用不同的访问修饰符将数据公开给某些类,而不能公开给其他类。

I bet he was waiting that you will refer to "immutable" types also. 我敢打赌,他在等待您也将提及“不可变”类型。

PD. PD。 private is no type, it is an access modifier. private是没有类型,它是访问修饰符。

也许,他的意思是封装作为信息隐藏。

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. 如果将setter和getter设为公开/受保护/默认,则可以访问不同级别的私有成员..如果将setter&getter设为私有,则数据实际上是隐藏的。 This last way to go makes no sense at all though 最后的路虽然没有任何意义

您可能会考虑以许多不同的方式实现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). 例如,假设您有一个具有(x,y)的set / get的Coordinate类。 The inner implementation might be based on polar coordinates: 内部实现可能基于极坐标:

private double radius;
private double angle;

and the get/set for (x, y) do some coordinate transformation with sin and cos. (x,y)的get / set与sin和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. 您可以随意将类的实现更改为任何其他坐标系,并且仍然仅将(x,y)的设置/获取保留为公共方法。

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). 因此,总而言之,我对这个问题的回答是:一个类的公共接口可以提供set / get,但是可以(并且应该)通过将所有成员设为私有(或受保护)来隐藏实际的实现。 So we could say that having public set/get on private data is "implementation hiding" rather than data hiding. 因此,可以说,对私有数据进行公共设置/获取是“实现隐藏”,而不是数据隐藏。

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. 存在这些概念是为了确保从类B(类B扩展了类A)的类A的继承不会继承“封装的”成员。

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. 您的问题对于OOPS概念非常基础。 And the interviewer is not trying to corner, you but ask you very basic questions on OOPS. 面试官并不是想corner逼人,而是向您询问有关OOPS的非常基本的问题。 Study hard!!! 努力学习!!!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM