问题
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?
回答1:
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.
}
回答2:
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, so 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 gave 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 to 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, so 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
回答3:
The real use of encapsulation is also in the fact that you can do additional checks/processing on the way the values are set.
回答4:
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.
回答5:
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.
回答6:
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
回答7:
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).
Better maintainability: When all the properties are private and encapsulated, it is easy for us to maintain the program simply by changing the methods.
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.
Have a Controlled Environment: Let the users use the given objects, in a controlled manner, through objects.
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)
回答8:
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:
- Encapsulated Code is more flexible and easy to change with new requirements
- Allows you to control who can access what. (!!!)
- Helps to write
immutable class
in Java - It allows you to change one part of code without affecting other part of code.
回答9:
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...
回答10:
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).
回答11:
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.
回答12:
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.
回答13:
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.
回答14:
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;
}
回答15:
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.
来源:https://stackoverflow.com/questions/16418571/what-is-the-use-of-encapsulation-when-im-able-to-change-the-property-values-wit