34

I try to understand a lot of times but I failed to understand this.

Encapsulation is the technique of making the fields in a class private and providing access to the fields via public methods. If a field is declared private, it cannot be accessed by anyone outside the class, thereby hiding the fields within the class.

How can we change the values of fields through setter methods? How do we prevent accessing the fields directly? What is the real use of encapsulation?

Tom
  • 16,842
  • 17
  • 45
  • 54
PSR
  • 39,804
  • 41
  • 111
  • 151

17 Answers17

40

Assume you have an age property.

The user can enter a value of -10, which although is a valid number, is an invalid age. A setter method could have logic which would allow you to catch such things.

Another scenario, would be to have the age field, but hide it. You could also have a Date of Birth field, and in it's setter you would have something like so:

...
private int age
private Date dob

...
public void setDateOfBirth(Date dob)
{
    this.dob = dob;
    age = ... //some logic to calculate the age from the Date of Birth.
}
npinti
  • 51,780
  • 5
  • 72
  • 96
31

I have also been confused like you too for a long time until I read the book Encapsulation and Inheritance in Object-Oriented Programming Language and a website that explained the importance of Encapsulation. I was actually directed from the website to the book.

People always say encapsulation is "hiding of information" therefore, maybe, making encapsulation focus on security as the main use. Yes you are hiding information in practice, but that should not be the definition as it could confuse people.

Encapsulation is simply "minimizing inter-dependencies among separately-written modules by defining strict external interfaces" (quoting from the book). That is to say that when I am building a module, I want a strict contract between my clients and me on how they can access my module. Reason being that, I can improve the inner workings without it AFFECTING my client's, life, application or whatever they are using my module for. Because their "module" does not exactly depend on the Inner workings of my module but depends on the "external interface", I made available to them.

So, if I don't provide my client with a setter and give them direct access to a variable, and I realize that I need to set some restriction on the variable before my client could use it, me changing it, could be me, changing the life of my client, or application of my client with HUGE EXPENSE. But if I provided the "strict contract" by creating a "strict external interface" i.e setter, then I can easily change my inner workings with very little or no expense to my clients.

In the setter situation (using encapsulation), if it happens that when you set a variable, and I return a message informing you that it has been assigned, now I could send a message via my "interface", informing my client of the new way my module have to be interacted with, i.e "You cannot assign negative numbers" that is if my clients try to assign negative number. But if I did not use encapsulation, and gave my client direct access to a variable and I do my changes, it could result in a crashed system. Because if the restriction I implemented, is that, you could not save negatives and my client have always been able to store negatives, my clients will have a crashed system in their hands (if that "crashed system" was a banking system, imagine what could happen).

So, encapsulation is more about reducing dependency between module, and an improvement can be made "quietly" with little or no expense to other modules interacting with it, than it is of security. Because the interacting modules depend on the "strict external interface or strict contract".

I hope this explains it properly. If not you could go the links below and read for yourself.

encapsulation matters

Encapsulation and Inheritance in Object-Oriented Programming Languages

Morteza
  • 642
  • 7
  • 17
Uche Dim
  • 412
  • 5
  • 7
  • This makes way more sense to me than the twenty other times I've read about encapsulation before. The idea of improving my code without effecting the client's application was the key for me. – tazboy Jan 19 '17 at 19:56
  • @UcheDim thanks for the informative answer. But I didn't get the point `you could not save negatives and my client have always been able to store negatives, my clients will have a crashed system in their hands`. The thing is as per the answer we can change the public interface without affecting the client which means I can put a check in setter to disallow -ve numbers. Now earlier my setter was allowing -ve values and now it doesn't. Won't this also crash their systems. Or did you mean that since we now provide an exception msg it won't. – Yug Singh May 08 '19 at 06:26
  • 1
    @YugSingh In the instance where you do not have a public interface and you give the client direct access to the variable, and you make changes i.e "you could use negative number before and after changes you could not anymore" the clients app or whatever they used the variable for will have error. But if there was a public interface i.e setter or getter, you will just alway return a message to inform the client what is allowed and what is not allowed or if the assignment was successful or not. With public interface, the client always knows what to expect, no matter the changes made within. – Uche Dim May 09 '19 at 12:27
  • this sentence of yours `Because their "module" does not exactly depend on the Inner workings of my module but depends on the "external interface", i made available to them.` explains abstraction not encapsulation – Morteza Oct 27 '20 at 19:52
  • @MortezaBandi It doesn't really. As you can see its in a quote so its not taking out of context. in this context you cant possibly think i am explaining abstraction. so when i said "external interface", i mean whatever i return or make available to the user. For example i might be manipulating an integer in a setter method but the "external interface" i will return to the user is string i.e "Could not set value because it is negative" or "setting value is successful". In this case the "external interface" they have access to is a message from my module and no access to the actual variable. – Uche Dim Oct 28 '20 at 13:26
  • @UcheDim. I know the context is about encapsulation and ... . But, I think using the term `external interface` might not be the best phrase to describe encapsulation as it implicitly defines abstraction. It is based on my experience and might not be 100 true for others. – Morteza Oct 28 '20 at 18:15
  • @MortezaBandi "External interface" is not describing encapsulation in my write up or explanation. It is used to describe what the client will be INTERACTING WITH . hence INTERFACE. the EXTERNAL is to make the reader understand the interaction is outside the method or module. In the context of my answer don't see how one will confuse the description of interacting with another module(External Interface) with ABSTRACTION that is a concept or idea in computing. – Uche Dim Feb 08 '22 at 15:56
13

The real use of encapsulation is also in the fact that you can do additional checks/processing on the way the values are set.

Eugene
  • 2,965
  • 2
  • 34
  • 39
6

You're not exactly preventing access to the fields -- you're controlling how others can access certain fields. For example you can add validation to your setter method, or you can also update some other dependent field when the setter method of a field is called.

You can prevent write or read access to the field (e.g. by only providing a getter or setter respectively) -- but encapsulation with properties allows you to do more than just that.

mikey
  • 5,090
  • 3
  • 24
  • 27
5

The main idea behind encapsulation is data hiding. There are several reasons why we use encapsulation in object oriented programming. Some of the identified reasons for why we encapsulation are as follows (The real use of encapsulation).

  1. Better maintainability: When all the properties are private and encapsulated, it is easy for us to maintain the program simply by changing the methods.

  2. Make Debugging Easy: This is in line with the above point. We know that the object can only be manipulated through methods. So, this makes it easy to debug and catch bugs.

  3. Have a Controlled Environment: Let the users use the given objects, in a controlled manner, through objects.

  4. Hide Complexities: Hiding the complexities irrelevant to the users. Sometimes, some properties and methods are only for internal use and the user doesn't have to know about these. This makes is simple for the user to use the object.

So, to answer the question, "What is the use of encapsulation when I'm able to change the property values with setter methods?", given above are some of the main reasons why we use encapsulation. To provide an understanding on why, getters and setters are useful, given below are some important points, obtained from this article.

  • You can limit the values that can be stored in a field (i.e. gender must be F or M).

  • You can take actions when the field is modified (trigger event, validate, etc).

  • You can provide thread safety by synchronizing the method.

  • You can switch to a new data representation (i.e. calculated fields, different data type)

Keet Sugathadasa
  • 11,595
  • 6
  • 65
  • 80
4

If you have private fields they can't be accessed outside the class, that means basically those fields don't exist to the outside world and yes you can change their value through setter methods but using setter methods you have more flexibility/control to say who gets to change the fields and to what value can they be changed to...basically with encapsulation you get to put restrictions on how and who changes your fields. For example you have: private double salary, you setter method could restrict that only hr staff can change the salary field it could be written as:

void setSalary(Person p,double newSalary)    
{    
//only HR objects have access to change salary field.   
If(p instanceof HR && newSalary>=0)    
//change salary.   
else   
 S.o.p("access denied");    
} 

Imagine if salary was public and could be access directly any can change it however and whenever they want, this basically the significance of encapsulation

Sello
  • 297
  • 1
  • 8
3

Any how i am able to change the values of fields through setter methods.

Only if the setter method lets you do that.

How we are preventing the accessing fields?

The setter and getter get to control if and how you can access the fields.

A setter may check if the value is valid. It may ask a SecurityManager if you should be allowed to do this. It may convert between data types. And so on.

Thilo
  • 257,207
  • 101
  • 511
  • 656
2

Lets suppose you make a custom Date class with the following setters / getters:

getDay() 
getMonth() 
getYear() 
setDay() 
setMonth() 
setYear()

Internally you could store the date using:

private int day;
private int month;
private int year;

Or you could store the date using a java.lang.Date-object:

private Date date;

Encapsulation doesn't expose how your class is working internally. It gives you more freedom to change how your class works. It gives you the option to control the access to your class. You can check if what the user enters is valid (you don't want the user to enter a day with a value of 32).

MMeersseman
  • 2,541
  • 1
  • 13
  • 8
1

It's aim is nothing but protecting anything which is prone to change. You have plenty of examples on the web, so I give you some of the advantages of it:

  1. Encapsulated Code is more flexible and easy to change with new requirements
  2. Allows you to control who can access what. (!!!)
  3. Helps to write immutable class in Java
  4. It allows you to change one part of code without affecting other part of code.
aran
  • 10,978
  • 5
  • 39
  • 69
  • You havd summed up many advantages which is good, but giving an example for each point would make it more useful. Just a suggestion. Thank you for writing this answer. – Solace May 27 '15 at 21:17
1

Accessing fields thru methods make difference because it makes it OOP. Eg you can extend you class and change the behaviour which you cannot do with direct access. If you have getters / setters you can make a proxy of your class and do some AOP or a make a 1.4 dynamic proxy. You can make a mock from your class and make unit testing...

Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
1

Encapsultaion is used for hiding the member variables ,by making member as private and access that member variable by getter and setter methods.

Example

class Encapsulation{

private int value ;

Encapsulation() {
    System.out.println("constructor calling ");
}

void setValue(int value){
    this.value = value;
}
int getValue() {
    return value;
}

} class EncapsulationMain {

public static void main(String args[]) {
    Encapsulation obj = new Encapsulation();
    obj.setValue(4);
    //System.out.print("value is "+obj.value); 
    //obj.value = 55;
    //System.out.print("obj changing the value"+obj.value);
    System.out.print("calling the value through the getterMethod"+obj.getValue());
}

}

you cannot access the private value outside the class.

1

Well, encapsulation is not all about hiding data. It is all about getting control over what is stored in the fields. Using encapsulation we can make a field as read-only or write-only depending upon the requirements.Also the users don't know how the data is stored in the fields. We can use some special encryption in the setter methods and store it in the fields. For example human is a object. We only require the name field of the human to be read by the user but not to be modified. Then we define only get method on the name field.This is how the encapsulation is useful.

0

If you have class all of its properties are private-meaning that they cannot be accessed from outside the class- and the only way to interact with class properties is through its public methods.

You are changing tha values by giving the public access to those methods(setters).

using encapsulation the fields of a class can be made read-only or write-only.

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
0

Instead of letting everyone access the variables directly:

public Object object;

Is better to use SET and GET methods, or for example just the GET method (Sometimes you dont want nobody to set other value to that variable).

public Object getObject() { 

return object;
}

public void setObject(Object object) { 

this.object = object;
}
user2245180
  • 161
  • 6
0

By using encapsulation you separate your class from the out-side world (other classes) and out-side world can access and modify your class instance variables through access modifiers, which provides several benefits:

-You can do some logging in your getter/setter methods.

-You can validate /normalize (for example trim spaces, remove special character,...) Your input in setter method.

And also you can hide your implementation from the outside world, for example you have a collection like array list in your class and you write your getter method like this

public List<t> get collection(){
 return new  ArrayList<t>(this.arrayList);
}

So in this case, in the future if you decide to change your implementation of collection from array list to something else like linked list, you are free to do so because out side world doesn't know anything about your implementation.

Mr.Q
  • 4,316
  • 3
  • 43
  • 40
0

Encapsulation is not about secrecy, it is about reducing dependency over separate part of the application.

We control dependency (loose / weak / low coupling) by hiding information over separate part of the application.

Adding to Uche Dim's answer, look at the following example:

Two Connections:

public class Area {

    // fields to calculate area
    private int length;
    private int breadth;

    // constructor to initialize values
    Area(int length, int breadth) {
        this.length = length;
        this.breadth = breadth;
    }

    public int getLength() {
        return length;
    }

    public void setLength(int length) {
        this.length = length;
    }

    public int getBreadth() {
        return breadth;
    }

    public void setBreadth(int breadth) {
        this.breadth = breadth;
    }

    public int getArea() {
        int area = length * breadth;
        return area;
    }
}

class Main {
    public static void main(String[] args) {

        Area rectangle = new Area(5, 6);

        // Two Connections
        int length = rectangle.getLength();
        int breadth = rectangle.getBreadth();
        int area = length * breadth;
        System.out.println("Area: " + area);
    }
}

Please note that in the Main class, we are calling two methods (getLength() and getBreadth()) of Area class.

One Connection:

public class Area {

    // fields to calculate area
    private int length;
    private int breadth;

    // constructor to initialize values
    Area(int length, int breadth) {
        this.length = length;
        this.breadth = breadth;
    }

    public int getArea() {
        int area = length * breadth;
        return area;
    }
}

class Main {
    public static void main(String[] args) {

        Area rectangle = new Area(5, 6);

        // One Connection
        int area = rectangle.getArea();
        System.out.println("Area: " + area);

    }
}

Here, in the Main class, we are calling one methods (getArea()) of Area class.

So in the second example, the connection is weaker than the previous one (first one calling two methods or the Area class, second one calling one method of the Area class). Given, less connection (lower / weaker coupling) is better, the second example is better.

We should always keep fields and methods private unless necessary. In the Two Connections example, we made the mistake of creating the getters unnecessarily. As we have created it, the IntelliJ Idea (auto suggestion of modern IDE) suggested the developer who was working on the Main class that you can use the getLength() and getBreadth() methods and he did. He did not inquire further to check if there was a getArea() method. As a result he created stronger coupling than necessary.

We should not unnecessarily create getters. We should not unnecessarily make fields public or protected. If you must, first try protected, if that does not work then make it public. That way we will have a lesser possibility of having a tighter coupling.

If you still have the question "what is the difference between making a field public compared to making a field private but it's getters public?", in other words "Why should we use a function to get a value instead of getting it directly?" Well it gives you another layer of abstraction. For example, if you need some extra processing of the data before receiving it (ex. validation), you can do it there. Moreover, once you expose internals of a class, you can not change that internal representation or make it better until making changes in all client codes. 

For example, suppose you did something like:

public class Area {

    private int length;
    private int breadth;

}

class Main {
    public static void main(String[] args) {

        Area rectangle = new Area(5, 6);

        int area = rectangle.length * rectangle.breadth;
        System.out.println("Area: " + area);
    }
}

Now, if you want to change breadth to width in Area class, you can not do it without breaking the program, unless you search and replace rectangle.breadth with rectangle.width in all the clients where rectangle.breadth was used (in this case Main class).

There are other benefits as well. For example, Member variables cannot be overridden like methods. If a class has getters and setters, it's subclass can override these methods and return what makes more sense in the context of subclass.

Please check Why getter and setter are better than public fields in Java? for more details.

P.S. These are trivial examples, but in large scale, when program grows and frequent change requests are a reality, this makes sense.

Ahmad Ismail
  • 11,636
  • 6
  • 52
  • 87
0

I'm OK with using get and set, to mask and make reengineering easier, but if you tell to a novice programmer that using get and set does encapsulation, as I've seen many times, they will use set and get for internal members initialized by the constructor. And this 99.9 % is wrong!!!!!

private uint8_t myvar = 0;

setMyVar(uint8_t value){ 
this.myvar = value * (20 / 41);
}
uint8_t  getMyVar(){
return this. myvar  ;
}

That’s for me is ok, but I think encapsulation is a method first, rather than get and set. My inglish is not very well,but I think that this article says something like this.