您如何决定定义变量“private”?
我参加了一次工作面试。面试官问我为什么需要私有变量。如果你通过定义一个变量 private 来实现某些目的,那么你不能通过定义 java 中定义的任何其他访问修饰符来实现同样的目的吗?
According to Java Specification Languages, A private class member or constructor is accessible only within the body of the top level class (7.6) that encloses the declaration of the member or constructor. It is not inherited by subclasses.
但是,如果我正在设计一个类,我如何决定定义一个变量“私有”?
I have attended a job interview. The interviewer asked me why you need private variable. If you achieve something by defining a variable private, can't you achieve the same by defining any other access modifier defined in java?
According to Java Specification Languages, A private class member or constructor is accessible only within the body of the top level class (7.6) that encloses the declaration of the member or constructor. It is not inherited by subclasses.
But, if i am designing a class, how can i take decision to define a variable "private"?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
通过限制“其他代码”(可能由其他人编写/维护)的访问,您将来可以更自由地更改它,而不必担心破坏依赖它的其他一些代码。
问题不是“我应该将其设为私有吗?”,而是“是否需要将其设为非私有?”。是否有其他代码可能需要访问该变量?
如果情况确实如此,您可以分配适当的访问权限(可能通过 getters/setters)并接受对其进行更改将很困难的事实。否则你就把它保留为私人的。
By limiting the access of "other code" (perhaps written/maintained by others) you are more free to change it in the future without having to worry about breaking some other code that relies on it.
The question is not "should I make this private?", but rather "is there a need for this to be non-private?". Is there some other code that is likely to need access to the variable?
If that turns out to be the case, you assign the proper access (possibly via getters/setters) and accept that changes to it will be difficult. Else you leave it private.
我认为你应该从另一个方向看它:为什么你要把一个变量设置为不是私有的?正确的封装意味着隐藏实现的细节,因此默认情况下应该将字段设为私有。
I think you should look at it from the other direction: why would you make a variable anything but private? Proper encapsulation means hiding the details of your implementation so the default should be to make fields private.
基本上,一旦您将变量公开,您就已经做出了承诺,并且永远不能反悔这个决定。未来的每个更改都会更改类的公共接口,这反过来意味着该类的每个用法都需要更改。对于公共API来说,这是不可想象的;你的库有效地破坏了向后兼容性。
即使对于私人使用的类来说,这也是一件大事。
那么您将来什么时候会将变量的范围更改为
private
呢?造成这种情况的原因有很多。最简单的是,您的类可能需要在每次变量值更改时执行某些操作(例如记录更改,或相应地更新其他变量)。或者您稍后决定根本不需要该变量,并且应该动态计算用户请求的值。如果您直接读取或设置变量,这是不可能的。相反,您的类需要通过禁止直接访问变量并在其位置提供适当的公共 getter/setter 方法来强制用户调用 getter/setter。
因为一般来说您永远无法预见此类未来的变化,因此将无变量
公开
已成为公认的最佳实践。 每个变量都应该是私有
(或者至少是内部的)。(有一个例外:在某些情况下,
final
变量可以安全地设为public
。例如,类似枚举的常量通常被实现为public final
> Java 库中的变量,因为它们永远不会改变,并且不需要访问控制,因为它们无论如何都是只读的)。Basically, once you make a variable
public
, you’re committed and can never go back on this decision. Every future change would change the public interface of your class, which in turn means that every usage of that class needs to be changed. For a public API, this is unthinkable; your library effectively broke backwards compatibility.Even for privately used classes, this is kind of a big deal.
So when would you ever change the scope of a variable to
private
in the future? There are many conceivable reasons for this. The easiest is that your class might need to do something every time the variable’s value is changed (e.g. log the change, or update other variables accordingly). Or you decide later on that the variable isn’t needed at all, and that the value that is requested by the user should be computed on the fly instead.If you’re directly reading or setting a variable, that’s not possible. Instead, your class needs to force the user to call a getter/setter, by forbidding direct access to the variable and offering appropriate public getter/setter methods in its place.
Because in general you can never foresee such future changes, it has become accepted best practice to make no variable
public
. Every variable should beprivate
(or at least internal).(There’s one exception: in some cases,
final
variables can safely be madepublic
. For example, enum-like constants are often implemented aspublic final
variables in Java libraries because they will never change, and no access control is required since they are read-only anyway).一般的经验法则是减少变量和方法的范围。保持私有的东西越多,您就越容易更改类,而不会导致系统其他部分出现问题(即:减少耦合)。
所以一般规则 private 应该是默认的
A general rule of thumb is to reduce the scope of variables and methods. The more things you keep private the more easily you can change your class with out causing problems in other parts in the system (ie: you reduce coupling).
So as a general rule private should be default
是的。这是真的。任何
private
都可以更改为public
(或protected
等),程序将像以前一样编译和运行。访问修饰符的存在是为了方便程序员,并帮助他正确定义类的接口。查看有关封装的维基百科文章。
Yes. That's true. Any
private
can be changed topublic
(orprotected
and so on) and the program will compile and run just as it did before.The access modifiers are there for the programmers convenience, and helps him properly define the interface of the class. Have a look at the wikipedia article on encapsulation.
所以,你必须问自己为什么它必须是私有的。那么,如何运用矛盾求真的理念呢?
可以公开吗?
如果答案是,您不希望人们能够直接访问和修改该属性,那么它就不能是公共的。
可以默认吗?
如果答案是,您不希望同一个包能够直接访问和修改该属性,那么它就不能是默认的。
可以保护吗
如果答案是,您不希望子类直接访问和修改该属性,那么它就不能受到保护。
因此,如果所有答案都是“否”(并且您必须确定为什么您不希望在这些情况下进行访问),那么它必须是私有的。
问题是,你是否真正理解修饰符给你带来了什么,以及如何访问它们,而不是盲目地将所有内容设为私有,并创建 setter 和 getter,因为这是你的讲师/书籍/手册教你的。
So, you have to ask yourself why it has to be private. So, how about using the truth by contradiction idea.
Can it be public?
If the answer is, you do not want people to be able to access and modify the attribute directly, then it cannot be public.
Can it be default?
If the answer is, you do not want the same package to be able to access and modify the attribute directly, then it cannot be default.
Can it be protected
If the answer is, you do not want subclasses to access and modify the attribute directly, then it cannot be protected.
Therefore, if all answers are No (and you have to determine the answers of why you don't want the access in those scenarios), then it must be private.
The question is asking, do you really understand what the modifiers give you, and how they can be accessed, and not to blindly make everything private, and create setters and getters, because that is what your lecturer/book/manual taught you.
在这种情况下,该成员是私有的:
。设计就是封装,这意味着您的类实现对客户端代码隐藏。它提高了代码的可读性、可维护性和可测试性。
the member is private in the cases:
The object of such design is encapsulation, which means that you has your class implementation hided from the client code. It improves readability, maintainability and testability of the code.
类的要点是封装数据和行为并隐藏内部实现,同时向外部公开干净、简单且有用的 API。
有两个不同的事情需要考虑:公共合约(API)和私有数据。
私有字段:这是您的私有数据,您不希望将其公开,因为:安全性和完整性。
私有方法:使代码更具可读性和可维护性的实用函数。
公共方法:您向其他人公开的契约(接口、API)。这就是使您的类变得有用的原因。
公共字段:不要使用它。它仅公开您的部分内部数据。对于简单的类来说可能没问题,而对于具有相互依赖字段的复杂类来说这是一个很大的禁忌。为了公开功能,您应该使用公共方法(第 3 点)。
The main point of classes is to encapsulate data and behavior and hide internal implementation, while exposing clean, simple and useful API externally.
There are two different things to consider: public contract (API) and private data.
Private fields: this is your private data, which you don't want exposed externally because of: security and integrity.
Private methods: your utility functions to make code more readable and maintainable.
Public methods: a contract (interface, API) that you expose to the other people. That's what makes your classes useful.
Public fields: don't use this. It exposes only part of your internal data. For simple classes might be ok, while for complex classes with interdependent fields this is a big no-no. For exposing functionality you should use public methods (point 3.).
其中许多注释适用于内部/嵌套类、方法和构造函数。
基本上,您希望在不造成过度复杂性的情况下尽可能限制访问。如果您可以将某些内容设为私有或静态,我建议您这样做。如果你能进行现场决赛,这通常也有助于提高清晰度。
当某个字段或任何成员是私有的时,您可以立即看到它在哪里使用以及何时不再使用。
Many of these comments apply to inner/nested class, methods and constructors.
Basically, you want to make access as restricted as possible without creating undue complexity. If you can make something private or static, I suggest you that. If you can make a field final, this usually help improve clarity as well.
When a field or any member is private you can immediately see where it is used and when its is no longer used.