Best practices regarding the use of access modifiers

Asked

Viewed 592 times

8

How to restrict other classes from accessing certain members (methods, variables/fields, nested classes/interfaces) one-class?

I would like to know the best practices for using the access modifiers of the members of a class. With this know the correct combination of access modifiers and the entities (classes, interfaces, enums, methods and variables) to which can be applied.

And know the implications of modifying the access modifier of a Java entity in day-to-day practice and use, not just the concepts of modifiers as in the question What is the difference between public, default, protected and private modifiers?

Show 2 more comments

2 answers

4


As you may already know, there are 4 types of java visibility:

  • public

  • private

  • protected

  • package-default (this is not a keyword, this is what happens when no modifier is used).

In mature and well-designed software projects, protected and the package-default are almost never used:

  • In the case of protected, the inheritance has been seen as something bad for a few years now. The reason is that inheritance introduces a strong subclass coupling to the superclass. When you use fields or methods protected and the superclass depends on them being used in certain ways by the subclasses, you also end up coupling the superclass to your subclasses. This goes against the good practices of object-oriented system design that value the weak coupling. With the use of project standards, it is possible to eliminate all inheritance cases and exchange them for composition except when you have to use third-party libraries that cannot be modified and that provide inheritance-imposing superclasses to be used.

  • In the case of package-default, if a class needs to selectively expose functionalities to other classes in the same package, but not to other classes, it is a sign that there is some problem of cohesion, coupling or of encapsulation.

So, unless you’re using some library that imposes draconian restrictions on you in a well-done project, there are almost no cases where it’s a good idea to use protected or package-default. Where they occur and are in fact the best alternative, it will probably be to circumvent some limitation of the language. So let’s focus on public and in the private:

In the case of fields/attributes that do not have both modifiers static and final, the correct modifier is the private and period. If you are tempted to use anything other than private in an attribute not-static or not-final (including forgetting to put the private), you’re doing something wrong.

The fields that are simultaneously static and final may be public provided they relate to values of primitive types or immutable objects. Even when private, it is still a good idea that they are primitive values or immutable objects.

A class must publish to others, an API (set of fields, methods, constructors and internal classes) that details the functionalities it offers to the other classes to be used. The parts of the class that are in this API that it offers to others receive the modifier public, and whatever is outside this set, should take the private. A method that represents a complete and important functionality of class business rule should probably be public. Something that represents a chunk of code that was in some method and that was separated in a new method just to be better organized, probably should be private.

For methods, builders and inner classes, you have to judge whether that is something that matters to other classes or not. The class should be done by seeking to value itself by encapsulation, high cohesion and low coupling, which will help to separate what it offers to the world from what is only an internal technical detail of the way it is implemented. This judgment is subjective and requires a good deal of experience to be done correctly, but most of the time, judging which is the best case is easy, although there are always some who are in the gray zone.

Starting from Java 8, interfaces can have static methods and with standard implementations (do not confuse the modifier default employee with visibility package-default, that is not the purpose of the modifier). This helps reduce the need to use the protected and the package-private. Combine this with the Ambids, and this need reduces further.

Up to Java 8, everything put inside a interface era public, even if the keyword public is not there (if you do not put the modifier public in a method of a interface, the compiler will pretend the modifier was there, there is no package-default for interface members). From Java 9, interfaces may have private methods as well (which must have the modifier private) and that are not inherited by the classes that implement this interface. This change in Java 9 serves to eliminate one of the very few cases where visibility package-default made sense, which was to provide (through auxiliary classes in the same package) functionalities with implementations to methods default or static interface that should not be inherited.

-1

Encapsulating and leaving attributes as Protected example:

protected String name;

Allowing only the methods of the heirs classes access and manipulate the attributes.

If we let Private example: Private String name; only methods of the same class can make changes, and if we leave Public all methods independent of class, can make changes.

In short.

protected In addition to maintaining the security of attributes, it only allows the methods of its class, and the methods of the heiring classes to make changes...

  • 1

    Access limiters do not serve to maintain "attribute security". They serve to maintain the interface of a class, as well as its encapsulation, consistent. Access restrictors should not be used indiscriminately. Minimum information on a module.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.