This question already has answers here:
Property and Encapsulation
(4 answers)
Closed 7 years ago.
I've just learned about OOP. I'm kind of confused about private members in a class.
I saw examples about setting variable members to private so it's not be changed anywhere else.
But on the other hand, there are public methods like getName() and setName() to get and set the private member Name for instance.
What is different between changing it through methods and changing it directly? Can anyone explain it for me, please?
The main argument for this pattern is encapsulation as described in this answer.
But admittedly in your name example there is not much encapsulation.
Here are two advantages of getter/setter methods vs public fields:
When setting a value through a setter method you can check and reject invalid values whereas if a field is public you can't control what values are assigned to it.
You don't need to provide a setter and getter method, giving you the possibility to make a field effectively read-only or write-only.
Changing it with methods give you more control on the logic you want to apply to access your member variables.
For example if a member variable is a readonly variable, you can omit the implementation of set method so nobody can write to the content.
Or on the other hand if you want to just write to a variable and don't want anybody read it later you can just implement set methods.
One other thing that setters will provide you is that you can have a validation before committing the value. For example if you expect a string of a certain format to be set to a member string variable, you can check it in the setter function and accept it if it matches the pattern or reject it if it doesn't.
It is generally the best practice to change/read the member variables through getters and setters
As a general rule of thumb, you want to be as restrictive as possible on your class properties and extension points (private > protected > public). This is particularly important in projects that run for a long period of time and need maintenance and re-factoring.
It's quite difficult to restrict your properties from public to protected/private once they have been used for a while, because you don't know how many other classes are relying on those properties being public. On the other hand, relaxing from private to protected/public is less traumatic because you don't have to worry about previous access to that property from without that class.
Having said that, getters and setters provide you with unique points of contact to interact with private members of a class. That's called encapsulation in OOP. That means that you can ensure that everyone that interacts with those properties are doing it in the same and consistent manner. A silly example would be normalization of the property:
private String name;
public void setName(String name) {
this.name = StringUtils.capitalize(name);
}
You're ensuring here that whoever sets a name does not need to care about its capitalization, because you're enforcing it through the setter. Same could apply to a getter, applying business rules as needed.
Compare that with accessing a public property which you then need to capitalize on your end every time you use it...
Finally, I'd say that blindly adding getters and setters to your objects is a bad practice. Only provide those accessors when there's a good reason for them to exist. For instance:
class Person {
private name;
public Person(String name) {
this.name = name
}
public String name() {
return name;
}
}
You normally don't set the name to a person, so we can omit that setter all together. But every person has a name. That being the case, you can enforce it via its constructor. This makes that distinction explicit, enhancing your design and preventing your object from being in a non-consistent state.
Read this forum post . You may find lot of valuable points to get understand the concepts.
http://www.cplusplus.com/forum/lounge/101305/
Following example class of getters and setters shows few good practices. We need to use const type qualifier etc. Also we can validate the values inside the implementation.
Eg:-
class ClassName{
string name;
int age;
int weight;
public:
void setName(string strName);
void setAge(int iAge);
void setWeight(int iWeight);
string getName() const { return name; }
int getAge() const { return age; }
int getWeight() const { return weight; }
};
I can summarize following good reasons of using accessors :
Making future changes easier
Encapsulation of behaviors with property
Insulating your public interface from change
Set different access levels
Validate values prior to setting or getting
Related
Is a realization of POM an example of encapsulation? Are all imported libraries, code builders (maven/gradel/..) and all used code in the project, which realization is based behind "closed doors", examples of encapsulation?
It is hard to say whether Page Object Model is an example of encapsulation. However, as wiki says about encapsulation:
In object-oriented programming (OOP), encapsulation refers to the
bundling of data with the methods that operate on that data, or the
restricting of direct access to some of an object's components. Encapsulation is used to hide the values or state of a structured
data object inside a class, preventing direct access to them by
clients in a way that could expose hidden implementation details or
violate state invariance maintained by the methods.
So if Page Object Model hides the values or state from direct access by other users, then it can be said that it is an exmaple of encapsulation.
One of the ways to achieve encapsulation is to use setter and getter methods and access modifiers. Let me show an example:
public class EncapsulatedPerson
{
private string name;
public string GetName()
{
return name;
}
public void SetName(string name)
{
this.name = name;
}
}
and Person without encapsulation. Any user of class NotEncapsulatedPerson can edit name:
public class NotEncapsulatedPerson
{
public string name;
}
I am working on some practice questions for the OCP 8.
One question featured a class with private fields and private getter methods. The correct answer was that this code violates encapsulation because the getter methods should have been public.
public class A {
private String a;
private String getA() { return a; }
}
However, another question featured a class with private fields and no getter methods at all. The correct answer was that this code follows encapsulation principles.
public class A {
private String a;
}
Assuming all data fields are private, shouldn't the order of most encapsulated to least be no getter methods, private getter methods and public getter methods?
I know my question might sound opinion-based, but the exam is not.
Private getter methods do not violate encapsulation. That is just nonsense.
I am not expressing an opinion here. It is a fact that a Java private method can only be called within the class that declares it. That is inside the boundary of encapsulation.
Either you have misread the OCP sample question and answer, or they have made a mistake.
Now it could be that what they were trying to ask was whether the example class was an example of good encapsulation or more generally of good OO design.
UPDATE
Seeing the example code, it is hard to say one way or another. It is too unrealistic to make a judgement. (The code is literally useless, but unless we know what its intended use was, we can't really call this bad design.)
Another answer seems to be arguing that private getters are useless. I disagree. Especially since a getter may do other things apart from simply returning a value. Consider this:
private synchronized void setBalance(int newBalance) {
this.balance = newBalance;
}
private synchronized int getBalance() {
return this.balance;
}
This ensures that the caller will see the current value of the balance field even if it was just updated by another thread. Sure we can do it other ways, but this way is good separation of responsibilities.
And there other that a private getter could legitimately do.
Because, if you make a getter as private, then there is no way to access that data member in another class. We use a getter to access the private data member in another class. So if you are making getter as private, then what is the use of that getter.
I have a singleton class containing a bunch of control data that needs to be kept synchronized with the rest of my application. As a result, there are many times which I want another class to be able to read the information but not modify it. Currently, this singleton class has many public variables. I don't want to use getter and setter functions because they are wordy and annoying. Also, there are a lot of variables.
If my singleton class is called ControlData, I could create a second create a second class called ImmutableControlData, where it has all the same members, but they are declared final. Then, when retrieving my singleton, I would return an ImmutableControlData, rather than a ControlData object. However, this means that I need to constantly maintain the ImmutableControlData class as well as the ControlData class (annoying...)
If I had const-pointers, I would just return a const-pointer to my ControlData object. What can I do in Java, instead?
Java does not have const correctness like C++.
You could make an interface that declares the methods to read the data, but not the methods to modify the data. Make the class that holds the data implement this interface. Methods elsewhere in your program that should only read the data, should accept the interface, not the class, as the parameter type. For example:
public interface ReadablePerson {
String getName();
}
public class Person implements ReadablePerson {
private String name;
#Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
// Elsewhere...
public void someMethod(ReadablePerson p) {
System.out.println(p.getName());
}
Ofcourse, in someMethod you could still subvert this by casting p to Person, but at least it requires some conscious effort (adding the cast), which should alert the programmer that (s)he is doing something (s)he shouldn't do.
An advantage of this solution is that you don't have to make a defensive copy of the data.
First: If your Class has so many members, you should try to split the class into littler ones. Maybe you can summerize some variables eg.
ControlflowVariables
StateVariables
If you want to restrict the access to the variables you have to use getter. IDE can create getters and setters for you. The access to variables are the same:
singletonClass.variable is not worst then singletonClass.getVariable()
If you want to restrict the access only at some points in your code then create a final copy of tha variable
final int variable = singletonClass.getInstance().variable;
Personally, I would not try to control access in this way. There is nothing you can to do to prevent bad programmers from misusing your class. Even in C++, they could use a simple const_cast to remove your "protection" and modify the singleton any way they like.
Instead, I would restructure the code to make it easy for others to do the right thing and hard for them to get it wrong. Segregate the interface for ControlData into two separate interfaces: one for reading the object and one for updating it. Then simply provide the two interfaces where they're needed.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why use getters and setters?
This is a newbie question. Is it very much necessary to use getmethods to access property values? Once the value has been assigned, one can get the values directory. For example, in the below code, displayName() can display firstName value without the help of any getter method. Or it is a standard coding standards that one must have getter and setter method or any other methods which gives that value?
class Test{
private String firstName;
public void setName(String fname){
firstName = fname;
}
public void displayName() {
System.out.println("Your name is " + firstName);
}
}
Tell, Don't Ask is an important principle in object-oriented design. Generally you should tell objects to do things rather than ask them questions. getters/setters every where discourage this practise because you are encouraged to reach inside an object and get to the fields (or even worse reach in and poke things about in the case of setters). This breaks encapsulation and makes your code harder to reason about.
In your particular case, I'd create an object called Name that has a constructor taking the name and single method to display it.
In Your case (to display the display name) it is not neccessary to provide Getter.
But if your want use the field in another class We need to provide the Getter method.
Getter and setters are a part of the standard interface for Java Beans and many frameworks like Hibernate expect them in place. That being said it is of course up to you to decide if and when you need them and for what purpose. They provide access to your private member variables and they can even give you the chance to do more than just plain get and set.
The point of OO software is reuse. This means that other programmers, or you years from now, can use the code for other systems.
When you have private member variables, and use get/set functions, you can change the internal implementation of the function without breaking all the other code that uses it.
Do always use Getter and Setter to access your properties!
You should take a look at this article...
Having private state, encapsulation is good, and in A LOT of cases this is the right thing. Suppose that your class is suppose to be Thread Safe, having public fields you can't ensure that.
On the other hand there are cases when this is useless! Suppose that you access your object only in one package, you are sure you will never export it, then why bother?
I do not have any links to support this, but it's what I do.
I try to avoid public fields if they are not static. So I just use protected and private fields. From within the class, you can access them without get/set, that's completely fine. From outside the class, always try to use get/set.
So your example code is completely fine to me. :)
EDIT: One exception for me is if I create a struct-like container class like this
class Point4D {
public int x1, x2, x3, x4;
}
Then I think that public fields are ok. It would be still better to make them private and name the getters public int x1() etc though. As soon as some methods are introduced to this container that change the state of the instance (like changing the values of x1/x2/x3/x4), I make them private and add get/set.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why use getters and setters?
I have read books on Java, saying that it is good to create setters and getters for variables such as x and y. For example:
public int getX(){
return x;
}
public void setX(int x){
this.x = x;
}
But what is the difference from that and
...(shape.x)... // Basically getX()
and
shape.x = 90; // Basically setX()
If setters and getters are better, what practical problems would arise?
Multiple reasons:
If you allow field access like
shape.x = 90
then you cannot add any logic in future to validate the data.
say if x cannot be less than 100 you cannot do it, however if you had setters like
public void setShapeValue(int shapeValue){
if(shapeValue < 100){
//do something here like throw exception.
}
}
You cannot add something like copy on write logic (see CopyOnWriteArrayList)
Another reason is for accessing fields outside your class you will have to mark them public, protected or default, and thus you loose control. When data is very much internal to the class breaking Encapsulation and in general OOPS methodology.
Though for constants like
public final String SOMETHING = "SOMETHING";
you will allow field access as they cannot be changed, for instance variable you will place them with getters, setters.
Another scenario is when you want your Class to be immutable, if you allow field access then you are breaking the immutability of your class since values can be changed. But if you carefully design your class with getters and no setters you keep the immutability intact.
Though in such cases you have to be careful in getter method to ensure you don't give out reference of objects(in case your class have object as instances).
We can use the private variables in any package using getters and setters.
Using getter and setter functions allow for constraints and encapsulation. Lets say x is the radius. shape.x = -10 would not make much sense. Also, if someone tries to set an illegal value, you can print an error, set a default value, or do nothing.
It is good practice to make member variables private so they cannot be modified directly by programs using them.
Mutator functions
Encapsulation
A lot of people have mentioned encapsulating the specifics of the implementation, which to me is the biggest reason to use getters and setters in a class. With this, you also get a lot of other benefits, including the ability to throw out and replace the implementation on a whim without needing to touch every piece of code that uses your class. In a small project, that's not a big benefit, but if your code ends up as a well-used (internal or public) library, it can be a huge benefit.
One specific example: complex numbers in mathematics. Some languages have them as a language or framework feature, others don't. I will use a mutable class as an example here, but it could just as easily be immutable.
A complex number can be written on the form a + bi with real and imaginary parts, lending itself well to [gs]etRealPart and [gs]etImaginaryPart.
However, in some cases it's easier to reason about complex numbers on polar form re^(iθ), giving [gs]etRadius (r) and [gs]etAngle (θ).
You can also expose methods like [gs]etComplexNumber(realPart, imaginaryPart) and [gs]etComplexNumber(radius, angle). Depending on the argument types these may or may not need different names, but then the class' consumer can use either as fits its needs.
The two forms are interchangeable; you can fairly easily convert from one to the other, so which form the class uses for internal storage is irrelevant to consumers of that class. However, consumers may use either form. If you choose the form a+bi for internal representation, and expose that using fields rather than getters and setters, not only do you force the class consumers to use that form, you also cannot later easily change your mind and replace the internal representation with re^(iθ) because that turns out to be easier to implement in your particular scenario. You're stuck with the public API you have defined, which mandates that specifically the real and imaginary parts are exposed using specific field names.
One of the best reasons I can think of for getters and setters is the permanence of a class's API. In languages like python you can access members by their name and switch them to methods later. Because functions behave differently than members in java once you access a property thats it. Restricting its scope later breaks the client.
By providing getters and setters a programmer has the flexibility to modify members and behavior freely as long as the adhere to the contract described by the public API.
Another good reason to user getter and setter can be understand by the following example
public class TestGetterSetter{
private String name ;
public void setName(String name){
this.name = name ;
}
public String getName(){
return this.name ;
}
}
The point of getters and setters is that only they are meant to be used to access the private variable, which they are getting or setting. This way you provide encapsulation and it will be much easier to refactor or modify your code later.
Imagine you use name instead of its getter. Then if you want to add something like a default (say the default name is 'Guest' if it wasn't set before), then you'll have to modify both the getter and the sayName function.
public class TestGetterSetter{
private String name ;
public void setName(String name){
this.name = name ;
}
public String getName(){
if (this.name == null ){
setName("Guest");
}
return this.name ;
}
}
There is no requirement for getters and setter to start with get and set - they are just normal member functions. However it's a convention to do that. (especially if you use Java Beans)
Let's say, hypothetically, you find a library that does a better job of what you have been doing in your own class (YourClass). The natural thing to do at this point is to make YourClass a wrapper interface to that library. It still has a concept of "X" which your client code needs to get or set. Naturally, at this point you pretty much have to write the accessor functions.
If you neglected to use accessor functions and let your client code access YourClass.x directly, you would now have to rewrite all of your client code that ever touched YourClass.x. But if you were using YourClass.getX() and YourClass.setX() from the beginning, you will only need to rewrite YourClass.
One of the key concepts of programming, and especially object oriented programming, is hiding implementation details so that they're not used directly by code in other classes or modules. This way, if you ever change the implementation details (as in the example above), the client code doesn't know the difference and doesn't have to be modified. For all your client code knows, "x" might be a variable, or it might be a value that is calculated on the fly.
This is an oversimplification and doesn't cover all the scenarios where hiding implementation is beneficial, but it is the most obvious example. The concept of hiding implementation details is pretty strongly tied to OOP now, but you can find discussions of it going back decades before OOP was dreamed up. It goes back to one of the core concepts of software development, which is to take a big nebulous problem, and divide it into small well-defined problems which can be solved easily. Accessor functions help keep your small sub-tasks separate and well-defined: The less your classes know about each other's internals, the better.
There are lots of reasons. Here are just a few.
Accessors, getters in particular, often appear in interfaces. You can't stipulate a member variable in an interface.
Once you expose this member variable, you can't change your mind about how it's implemented. For example, if you see a need later to switch to a pattern like aggregation, where you want the "x" property to actually come from some nested object, you end up having to copy that value and try to keep it in sync. Not good.
Most of the time you are much better off not exposing the setter. You can't do that with public fields like x.
Before get into the answer, we gotta know something prior...! "JavaBeans".
JavaBeans are java classes that have properties. For our purpose, think of properties as private instance variables. since they're private, the only way they can be accessed
from outside of their class is through 'methods'in the class.
The methods that change a propertiy's value are called setter methods, and the methods that retrieve a property's value are called getter methods.
I would say that neither the getters/setters nor the public members are good Object Oriented design. They both break OOP Encapsulation by exposing an objects data to the world that probably shouldn't be accessing the properties of the object in the first place.
This is done by applying the encapsulation principle of OOP.
A language mechanism for restricting access to some of the object's components.
This means, you must define the visibility for the attributes and methods of your classes. There are 3 common visibilities:
Private: Only the class can see and use the attributes/methods.
Protected: Only the class and its children can see and use the attributes/methods.
Public: Every class can see and use the attributes/methods.
When you declare private/protected attributes, you are encouraged to create methods to obtain the value (get) and change the value (set). One example about visibility is the [ArrayList][2] class: it has a size property to know the actual size of the inner array. Only the class must change its value, so the code is something like
public class ArrayList<E> {
private int size;
private Object[] array;
public getSize() {
return this.size;
}
public void add(E element) {
//logic to add the element in the array...
this.size++;
}
}
In this example, you can see that the size value can change only inside the class methods, and you can get the actual size by calling it in your code (not mutating it):
public void someMethod() {
List<String> ls = new ArrayList<String>();
//adding values
ls.add("Hello");
ls.add("World");
for(int i = 0; i < ls.size(); i++) {
System.out.println(ls.get(i));
}
}
Getters and setters encapsulate the fields of a class by making them accessible only through its public methods and keep the values themselves private. That is considered a good OO principle.
Granted, it often seems like redundant code if it does nothing more than setting or returning a value. However, setters also allow you to do input validation or cleanup. Having that in one place improves data integrity for your objects,
Because we are using Object oriented programming language.
Here we are using Data hiding and encapsulation.
The variable should not directly accessible from out side world (for achiving data hiding) so we will create it private so
shape.x
is not correct.
Getter and setter method are used to get and set the value of x which is the way to achive encapsulation.