Pregunta

I know this applies to many languages, and not just Java, but that is the language I'm most familiar with.

I understand what the modifiers do, and how to use them. I just want to know, why do we need them? Why can't every object be accessible, whether or not it needs to be?

¿Fue útil?

Solución

The reason becomes more apparent when you have to maintain a larger project. When a method or variable is public, you have to be careful when you make changes to it, because you never know which parts of the codebase rely on its exact behavior.

But when a variable or method is private, you know that it is not used outside of the class. That means there is a lot less code you have to pay attention to when you make changes.

By making class features private and public, you clearly separate the interface to the outside world from the internals. The less you exposes to the outside world, the more freedom you have with what the internal implementation does.

When you, for example, always make variables private and accessed them through getters and setters, you can later change them from a variable to a computed value, and then even later add caching to the computation for performance reasons. When it would be a public variable, you would have to change code everywhere the variable is used. But when you expose it to the outside world through getters and setters, all other code can keep using the class as if nothing had changed.

Otros consejos

Making fields and methods private keeps other classes from improperly depending on the specific details of how a class works. The public interface (and the best case of all, an actual interface) describes how client code should interact with a library based on the semantics of the work being done. The implementer is then free to use whatever appropriate techniques to implement that interface and can make significant behind-the-scenes changes knowing that the client code will keep working.

An everyday example is the Collections group of interfaces. Most of the time, it's not important logically for code to know what particular kind of Set is in use, just that it's a collection that supports certain operations and doesn't have duplicates. This means that a method that accepts a Set<Integer> will work with any Set, including HashSet and ImmutableSet, because the person who wrote the interface wasn't poking around in the implementation's internals.

An example where this breaks down is the unfortunate tendency of some programmers to use packages in the com.sun namespace, especially when using cryptography. Upgrading to a new version of the JRE routinely breaks this code, which would have worked fine if the programmer had used the proper javax.crypto interfaces and factory methods instead of poking around in the JVM internals.

More or less they are used to control who can access your member variables and functions. It's the broader concept of encapsulation at work in Java(http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)).

From the Oracle Docs:

Access level modifiers determine whether other classes can use a particular field or invoke a particular method. There are two levels of access control:

At the top level—public, or package-private (no explicit modifier).

At the member level—public, private, protected, or package-private (no explicit modifier).

http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

As to why you should do this:

It has to do with intent of use. It would probably be best described as a design choice that helps guide usage through-out the code-base. By marking something private you are telling other developers that this field or method should not be used outside it's current purpose. It really becomes important on large projects that shuffle developers over time. It helps communicate the purpose & intended uses of classes.

To avoid other classes having direct access to internal members of the class.

This is most useful for avoiding that member variables are mutated in an uncontrolled way (e.g. without proper validation, without notifying listeners, ...).

Another reason to avoid this is that the internal implementation may change at any time but you don't want to break code that uses it.

As others have noted, the concept is called Encapsulation.

Access modifiers are there to set access levels for classes, variables, methods and constructors. This provides an individual with the chance of controlling better the privacy of the application. There are 4 access modifiers.

Modifier | Class | Package | Subclass | World

no modifier:--|----yes----|------yes--------|--------no--------|-----no----|


private:-------|----yes----|-------no--------|--------no--------|-----no----|


public:--------|----yes----|------yes--------|-------yes-------|----yes----|


protected:---|----yes----|------yes--------|-------yes-------|-----no-----|


Regarding your question, we do need and use access modifiers because we need to restrict whom can call our program and in what way.

Also, when it comes to variables if you make something public, that means that I have direct access to it. Therefore, I am allowed to do whatever I want without following your guidelines through your methods.

For example:

public int maxUsers;


public void setMaxUsers(int users) throws IllegalArgumentException{
   if(users > 0 && users <= 1000){
      maxUsers = users;
   }else{
      throw new IllegalArgumentException("The users can not be less than 0 or greater than 1000")"
   }
}

Imagine your whole program being based on its maxUsers. Since, you give me the right to access that variable directly, I could do this: maxUsers = -15; and not use the setMaxUsers method, which will simply make your program behave in an abnormal way (in the best case).

Explanations

A private member is only accessible within the same class as it is declared. A member with no access modifier is only accessible within classes in the same package.

or

If a variable is set to protected inside a Class, it will be accessible from its sub classes defined in the same classes or different package only via Inheritance.

A protected member is accessible within all classes in the same package and within subclasses in other packages.

A public member is accessible to all classes (unless it resides in a module that does not export the package it is declared in Here's a better version of the table. (Future proof with a column for modules.)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top