Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Encapsulation - why do we need it when setters are already public? [duplicate]

Encapsulation is hiding the data. I would like to hear some really interesting answers here.

What is the point behind keeping variables as private when we already declare public setter methods for variables?

I understand the usage of encapsulation but when we are making the setters as public what is the point behind keeping the variables as private, we can directly use public access modifiers.

Is it because we do not want others to know the exact way we are storing data or managing data on the back-end?

like image 577
Danyal Sandeelo Avatar asked Sep 16 '15 08:09

Danyal Sandeelo


People also ask

Why do we need to use encapsulation?

It refers to the bundling of data with the methods that operate on that data. Encapsulation is used to hide the values or state of a structured data object inside a class, preventing unauthorized parties' direct access to them.

Do encapsulation allows setters?

Advantage of Encapsulation in JavaBy providing only a setter or getter method, you can make the class read-only or write-only. In other words, you can skip the getter or setter methods. It provides you the control over the data.

Why do we need encapsulation in Java?

In Java, encapsulation helps us to keep related fields and methods together, which makes our code cleaner and easy to read. Here, we are making the age variable private and applying logic inside the setAge() method. Now, age cannot be negative. It helps to decouple components of a system.

Is setter method a violation of encapsulation?

Exposing properties directly using getters and setters, and exposing collection properties (even without setters) are two of the most common violations of encapsulation.


3 Answers

Is it because we do not want others to know the exact way we are storing data or managing data on the back-end?

Yes, that's the point. It is related to the concepts of abstraction and information hiding too.

You provide a public setter that when invoked by the class client will have the effect that you have documented. It is none of the client's business how this effect is actually achieved. Are you modifying one of the class attributes? Ok, let the client know that, but not the fact that you are actually modifying a variable. In the future, you could want to modify your class so that instead of a simple backup variable it uses something completely different (a dictionary of attributes? An external service? Whatever!) and the client will not break.

So your setter is an abstraction that you provide to the client for "modify this class attribute". At the same time you are hiding the fact that you are using an internal variable because the client doesn't need to know that fact.

(Note: here I'm using the word "attribute" as a generic concept, not related to any concrete programming language)

like image 169
Konamiman Avatar answered Sep 20 '22 18:09

Konamiman


I fully agree with Konamiman's answer, but I'd like to add one thing:

There are cases where you really don't want that abstraction. And that's fine.

A simple example I like to use here is a class for a 3-dimensional float vector:

class Vector3f { public:     float x;     float y;     float z; }; 

Could you make those fields private and provide setters instead? Sure, you could. But here you might argue that the class is really just supposed to provide a tuple of floats and you don't want any additional functionality. Thus adding setters would only complicate the class and you'd rather leave the fields public.

Now, you can easily construct scenarios where that might bite you later on. For instance, you might one day get a requirement that Vector3fs are not allowed to store NaNs and should throw an exception if anyone tries to do so. But such a hypothetical future problem should not be enough to justify introducing additional abstractions.

It's your call as a programmer to decide which abstractions make sense for the problem at hand and which ones would only get in your way of getting the job done. Unnecessary abstractions are over-engineering and will hurt your productivity just as much as not abstracting enough.

Bottom line: Don't blindly use setters everywhere just because someone claimed that's good practice. Instead, think about the problem at hand and consider the tradeoffs.

like image 36
ComicSansMS Avatar answered Sep 22 '22 18:09

ComicSansMS


Because by encapsulation we provide single point of access. Suppose you define a variable and its setter as follows

String username; 

public void setUsername(String username){
this.username = username;
}

Later you like to add some validation before setting username property. If you are setting the username at 10 places by directly accessing the property then you don't have single point of access and you need to make this change at 10 places. But if you have one setter method then by making a change at one place you can easily achieve the result.

like image 27
Jawad Avatar answered Sep 23 '22 18:09

Jawad