可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
This question already has an answer here:
-
Why use getters and setters/accessors? [closed]
38 answers
In object oriented programming, I used to have this question and I still do :
What would be the benefit of declaring a class member as private if we
will create for it a public getter and a public setter?
I don't see any difference at the security level between the case above and the case of declaring the class member as public.
Thanks!
回答1:
Encapsulation provides data hiding and more control on the member variables. If an attribute is public then anyone can access it and can assign any value to it. But if your member variable is private and you have provided a setter for it. Then you always have an option to put some constraints check in the setter method to avoid setting an illogical value.
For example a class with public member only :
class MyClass {
public int age;
}
public MyClassUser {
public static void main(String args[]) {
MyClass obj = new MyClass();
obj.age = -5 // not a logical value for age
}
}
Same class with private member and a setter:
class MyClass {
private int age;
public void setAge(int age) {
if(age < 0) {
// do not use input value and use default
} else {
this.age = age;
}
}
}
回答2:
If your class has no invariants to maintain then writing public getters and setters for a private data member is pointless; you should just use a public data member.
On the other hand, if you do have invariants to maintain then using a setter can allow you to restrict the values that can be assigned to the data member.
Note that just because you have a data member doesn't mean you have to write any getters or setters for it.
Pet peeve: "but what if the internals change?" It doesn't matter. You had a getName
function that returned a std::string const&
. Getters reduce encapsulation because they constrain your choices when changing the implementation later on.
回答3:
http://en.wikipedia.org/wiki/Encapsulation_%28object-oriented_programming%29
You could later change the internal representation of the class member, add functionality to the getter and setter (such as notifying an Observer), all without changing the interface (the public getter and setter).
回答4:
Your question is indeed the difference between Fields and Properties. Fileds are usually private and properties do expose them. Bellow is a quote of a brilliant answer on SO:
Properties expose fields. Fields should (almost always) be kept
private to a class and accessed via get and set properties. Properties
provide a level of abstraction allowing you to change the fields while
not affecting the external way they are accessed by the things that
use your class.
What is the difference between a Field and a Property in C#?
In C# automatic properties will create a filed for you without having to manually declare it:
public Prop { get; set; }
public Prop { public get; private set; }
public Prop { private get; public set; }
// etc, you can specify access modifier as per your need
回答5:
Quick (and a bit silly) example:
class Foo {
private int age = -1; // unset value
public setAge(int a) {
if (a < 0) {
throw new IllegalArgumentException("Invalid age "+a);
}
age = a;
}
public getAge() {
if (age < 0) {
throw new InvalidStateException("Age was not previously set.")
}
return age;
}
}
In short: you gain control and you can assure values are correct. It's called encapsulation.
回答6:
I don't see any difference at the security level between the case above and the case of declaring the class member as public.
Immediate question are :
1)What if you want to check some conditions,While setting the value ?
2)What if the subclassess want to return or set something else,by ovveridng that method ?
Other reason:Why getter and setter are better than public fields in Java
回答7:
If you have a data transfer object, with limited scope and by design it should have no logic associated with it, I don't see a value in getters and setters.
However, if you have a component which may or may not have some logic associated with it or it could be widely used, then it makes sense to hide the details of how the data is stored. Initially it might appear that all the getters and setters are trivial and just fill up you class, but over time you might add validation to the setters and even change the getters. e.g. you might drop a field (and return a constant in future), store the data in a delegated object or compute the value from other fields.
回答8:
Beside the encapsulation, consider a situation where your setter is not simply sets a value.
What if you're using it in many classes? And now you realize you want to change the functionality of it? You'll have to change it in whole places where you manually set it. Whereas if you had a setter life would have been easier.
回答9:
Accessor methods provide a single point of update for a given field. This is beneficial because validation logic or other modifications to the field can be controlled via the single method as opposed to having the field directly accessed throughout the code base.
See this IBM document which details more benefits: http://www.ibm.com/developerworks/java/library/ws-tip-why.html
回答10:
If the public getter and public setter are just to return the value of the private property and to change its value, then I see no difference.
However, you are implementing encapsulation, so in a later moment you can implement a different behavior, including argument check for setter or write-only/read-only properties, for instance.
回答11:
Actually, if you're developping alone on a small project and you won't reuse your code, it's kinda useless, but it's mostly a good habbit.
But, in team developpment, you may need to have some control on modification, and you can do it through the getters and setters.
Moreover, in some classes, you'll only have getters, as the setters will be done by the constructor, or via some other functions.
回答12:
Declaring variables as private
is called as Encapsulation in Java
.
Here are few advantages of using Encapsulation while writing code in Java or any Object oriented programming language:
- Encapsulated Code is more flexible and easy to change with new requirements.
- Encapsulation in Java makes unit testing easy.
- Encapsulation in Java allows you to control who can access what.
- Encapsulation also helps to write immutable class in Java which are a good choice in multi-threading
environment.
- Encapsulation reduce coupling of modules and increase cohesion inside a module because all piece of one thing
are encapsulated in one place.
- Encapsulation allows you to change one part of code without affecting other part of code.
one more advantage is
Making variables private in java and providing getter and setter for them makes your class compatible Java bean naming convention
回答13:
As with any encapsulation: it hides implementation details. This allows you to control access and provide a stable interface even when the internals change.
Setter controlling access
class Person //version 1.0
{
std::string name;
public:
std::string getName() const { return name; }
void setName(const std::string &newName)
{
if (!newName.empty()) //disallow empty names
name = newName;
}
};
Getter useful during API evolution
class Person //version 1.1
{
std::string firstName;
std::string lastName;
public:
std::string getFirstName() const { return firstName; }
void setFirstName(const std::string &newFirstName)
{
firstName = newFirstName;
}
std::string getLastName() const { return lastName; }
void setLastName(const std::string &newLastName)
{
if (!newLastName.empty()) //disallow empty last names
firstName = newFirstName;
}
std::string getName() const
{
std::ostringstream s;
if (!firstName.empty())
s << fistName << ' ';
s << lastName;
return s.str();
}
void setName(const std::string &newName)
{
setFirstName(splitUntilLastSpace(newName));
setLastName(splitFromLastSpace(newName));
}
};
回答14:
I have only one thing to add to the excellent answers that this post have so far.
Sometimes a class attribute could have more than one Getter or Setter, let's illustrate with a silly short example:
class Angle
{
public:
void Set(MyAngleTypedef a_value) { m_angle = a_value; }
// Note the 'Radians' type
void SetRadians(Radians a_value) { m_angle = ConvertRadiansToOurUnit(a_value); }
// Note the 'Degrees' type
void SetDegrees(Degrees a_value) { m_angle = ConvertDegreesToOurUnit(a_value); }
void Get(MyAngleTypedef a_value) const { return m_angle; }
// Note the 'Radians' type
Radians GetRadians(Radians a_value) const { return ConvertOurUnitToRadians(m_angle); }
// Note the 'Degrees' type
Degrees GetDegrees(Degrees a_value) const { return ConvertOurUnitToDegrees(m_angle); }
private:
// Raw value of the angle in some user-defined scale.
MyAngleTypedef m_angle;
}
Is meaningless to store the value more than once for each unit type which you want to work, so the Getters and Setters will provide an interface that makes the class able to work with different units.
IMHO, when a object contains active attributes (attributes that must do some work after or before it is assigned or accessed) it must be a class
with only the essential Getters and Setters (the private attributes that doesn't need accessed outside the class, obviously doesn't need public Getters and Setters).
In the other hand if an object conains only passive attributes (attributes that doesn't need extra work when assigned or accessed) it must be a struct
and therefore all his attributes would be public accesible without Getters and Setters.
Note that this answer is from the c++ point of view, check this question for more information.
回答15:
One of the most important concepts of Object Oriented Programming is encapsulation. You encapsulate data and the methods that act on that data together. Ideally, data should be accessed only via its related methods. And the state of data should be "queried" by other objects via these methods. Making a variable public will result in that variable being directly available to all other objects breaking encapsulation.